Skip to content

[FPP 10] FPP-Plugin-Projector-Control - compatibility & plugin check #205

Description

@github-actions

FPP-Plugin-Projector-Control - FPP 10 readiness

Plugin name: Projector Control
Repo: https://github.com/FalconChristmas/FPP-Plugin-Projector-Control
Maintainer: FalconChristmas org. Confirmed committers: @darylc, @dkulp, @patdelaney, @Poporacer

📢 FPP's plugin guidelines and submission process have been updated - see the Plugin Guidelines for what's expected of a listed plugin. Adding another plugin? Start at Submit a plugin.

🔄 As part of this new process, in the lead up to each new version release we will create a GitHub issue like this one and ask that you review compatibility of your plugin with the new version and outline any new best practices for plugins. Please review this information and update your plugin accordingly.

🧪 Get your plugin ready for FPP 10

FPP 10.0 beta3 has been released - FPP 10 full release is due shortly. Please test and update your plugin against beta3, available at https://github.com/FalconChristmas/fpp/releases/tag/10.0-beta3.

✅ Compatibility

A versions[] entry already declares FPP 10 support.

Areas of concern / optimisation

  • 🛑 Blocker - world-writable
    • loosens permissions to world-writable (fpp_install.sh:4: /usr/bin/sudo /bin/chmod a+w /dev/tty*) - since install/hooks already run as root, and the fpp runtime user is already in the dialout/tty/gpio groups that own these device nodes, there's no need to open the device to everyone - either drop the chmod entirely (group access already covers it) or scope it to the group, e.g. chmod 660
  • ⚠️ Best practice - stale-issues-prs
  • ⚠️ Best practice - destructive-no-csrf
    • destructive action with no method/CSRF guard (functions.inc.php:141: if (unlink($file)) {) - if this runs on a plain page load (not just internal cleanup after writing a replacement file, or stopping a process this same request started), it's reachable via a plain GET request with no confirmation.
    • Require $_SERVER['REQUEST_METHOD'] === 'POST' (or check a $_POST field) before running it if so
  • ⚠️ Best practice - device-path-no-allowlist
    • device path built from a variable with no allow-list check (proj.php:52: $SERIAL_DEVICE="/dev/".$DEVICE;) - if that variable traces back to request data (not just an admin-configured setting), a value like ../../etc/passwd makes this open an arbitrary path instead of a serial device.
    • Validate it against an allow-list pattern first, e.g. ^tty(USB|ACM|AMA)\d+$
  • ⚠️ Best practice - sudo
    • uses sudo in a script (fpp_install.sh:4: /usr/bin/sudo /bin/chmod a+w /dev/tty*) - install/hooks already run as root.
    • Remove the sudo call and run the command directly, e.g. /usr/bin//bin/chmod a+w /dev/tty*
  • ⚠️ Best practice - no-set-e
    • fpp_install.sh has no 'set -e' (or || exit) - without it, bash keeps running the rest of the script even after a command fails, so if an earlier step errors out (e.g. a dependency install fails), later steps still run against that broken state and the plugin ends up half-installed with no visible error.
    • Add set -e (or set -euo pipefail) as the first line after the shebang so the script stops immediately on the first failure instead
  • ⚠️ Best practice - no-restart-flag
    • registers command type(s) via commands/descriptions.json but doesn't request an fppd restart at every lifecycle point that needs one - uninstall: fpp_uninstall.sh present, no restart/reboot flag.
    • fppd only reads commands/descriptions.json and loads a native plugin's .so once, at its own startup (PluginManager::loadUserPlugins(), called once from fppd.cpp) - never again while running, and never in response to a plugin install/upgrade/uninstall.
    • Each lifecycle point runs independently (a plugin-only update runs fpp_upgrade.sh INSTEAD of fpp_install.sh when one exists; uninstall runs fpp_uninstall.sh then unconditionally deletes the plugin directory, so that script is the only code that ever runs before removal), so the flag has to be set independently in each one this plugin actually has/needs - fixing it in one script does not cover the others.
    • Add source ${FPPDIR}/scripts/common; setSetting restartFlag 1 to each script listed above (creating fpp_install.sh/fpp_uninstall.sh if missing - only fpp_upgrade.sh is optional, and only needs it if you already have one) so the Plugin Manager's restart banner appears right after that step instead of leaving the command silently unavailable/lingering as a ghost until fppd happens to restart for an unrelated reason
  • ⚠️ Best practice - log-naming
    • log filename doesn't follow the plugin-.log convention (commonFunctions.inc.php:5: $logFile = $settings['logDirectory']."/".$pluginName.".log";).
    • Name it plugin-FPP-Plugin-Projector-Control.log (not just FPP-Plugin-Projector-Control.log), so it's recognized as this plugin's log by FPP's log viewer and namespaced against collisions with other plugins/tools
  • ⚠️ Best practice - error-reporting-suppressed
    • error_reporting(0) silences PHP errors (proj.php:7: error_reporting(0); //commented out was in file pat 2/4/2024) - a fatal error in this script now fails silently (blank output, nothing in the log) instead of surfacing where it can be debugged.
    • Remove it, or narrow it to a specific error_reporting level you actually intend to suppress
  • 💡 Optional - no-license - no LICENSE file - add one for redistribution clarity

We know our automated checks don't always get it 100% right. Please fix whatever above does apply first - then, for anything left that doesn't apply or you think deserves an exception, comment /submit with an explanation and a maintainer will take a look.

Once you have updated your plugin, please comment /recheck on this issue and we will automatically scan your plugin and comment the new results here.

Want to sunset this plugin? Request Plugin Removal

Activity

  1. github-actions commented on Aug 10, 2026

    @github-actions
    ContributorAuthor

    🔄 Forced recheck (remediation sweep) - re-verifying with a real clone+lint pass after a bug let status be set from a metadata-only scan without one.

    FPP-Plugin-Projector-Control - FPP 10 readiness

    Plugin name: Projector Control
    Repo: https://github.com/FalconChristmas/FPP-Plugin-Projector-Control
    Maintainer: FalconChristmas org (org mentions don't reliably notify anyone). Confirmed committers: darylc, dkulp, patdelaney, Poporacer (not @-mentioned automatically)

    📢 FPP's plugin guidelines and submission process have been updated - see the Plugin Guidelines for what's expected of a listed plugin. Adding another plugin? Start at Submit a plugin.

    🔄 As part of this new process, in the lead up to each new version release we will create a GitHub issue like this one and ask that you review compatibility of your plugin with the new version and outline any new best practices for plugins. Please review this information and update your plugin accordingly.

    🧪 Get your plugin ready for FPP 10

    FPP 10.0 beta3 has been released - FPP 10 full release is due shortly. Please test and update your plugin against beta3, available at https://github.com/FalconChristmas/fpp/releases/tag/10.0-beta3.

    ✅ Compatibility

    A versions[] entry already declares FPP 10 support.

    Areas of concern / optimisation

    • 🛑 Blocker - world-writable
      • loosens permissions to world-writable (fpp_install.sh:4: /usr/bin/sudo /bin/chmod a+w /dev/tty*) - since install/hooks already run as root, and the fpp runtime user is already in the dialout/tty/gpio groups that own these device nodes, there's no need to open the device to everyone - either drop the chmod entirely (group access already covers it) or scope it to the group, e.g. chmod 660
    • ⚠️ Best practice - stale-issues-prs
    • ⚠️ Best practice - destructive-no-csrf
      • destructive action with no method/CSRF guard (functions.inc.php:141: if (unlink($file)) {) - if this runs on a plain page load (not just internal cleanup after writing a replacement file, or stopping a process this same request started), it's reachable via a plain GET request with no confirmation.
      • Require $_SERVER['REQUEST_METHOD'] === 'POST' (or check a $_POST field) before running it if so
    • ⚠️ Best practice - device-path-no-allowlist
      • device path built from a variable with no allow-list check (proj.php:52: $SERIAL_DEVICE="/dev/".$DEVICE;) - if that variable traces back to request data (not just an admin-configured setting), a value like ../../etc/passwd makes this open an arbitrary path instead of a serial device.
      • Validate it against an allow-list pattern first, e.g. ^tty(USB|ACM|AMA)\d+$
    • ⚠️ Best practice - sudo
      • uses sudo in a script (fpp_install.sh:4: /usr/bin/sudo /bin/chmod a+w /dev/tty*) - install/hooks already run as root.
      • Remove the sudo call and run the command directly, e.g. /usr/bin//bin/chmod a+w /dev/tty*
    • ⚠️ Best practice - no-set-e
      • fpp_install.sh has no 'set -e' (or || exit) - without it, bash keeps running the rest of the script even after a command fails, so if an earlier step errors out (e.g. a dependency install fails), later steps still run against that broken state and the plugin ends up half-installed with no visible error.
      • Add set -e (or set -euo pipefail) as the first line after the shebang so the script stops immediately on the first failure instead
    • ⚠️ Best practice - no-restart-flag
      • registers command type(s) via commands/descriptions.json but doesn't request an fppd restart at every lifecycle point that needs one - uninstall: fpp_uninstall.sh present, no restart/reboot flag.
      • fppd only reads commands/descriptions.json and loads a native plugin's .so once, at its own startup (PluginManager::loadUserPlugins(), called once from fppd.cpp) - never again while running, and never in response to a plugin install/upgrade/uninstall.
      • Each lifecycle point runs independently (a plugin-only update runs fpp_upgrade.sh INSTEAD of fpp_install.sh when one exists; uninstall runs fpp_uninstall.sh then unconditionally deletes the plugin directory, so that script is the only code that ever runs before removal), so the flag has to be set independently in each one this plugin actually has/needs - fixing it in one script does not cover the others.
      • Add source ${FPPDIR}/scripts/common; setSetting restartFlag 1 to each script listed above (creating fpp_install.sh/fpp_uninstall.sh if missing - only fpp_upgrade.sh is optional, and only needs it if you already have one) so the Plugin Manager's restart banner appears right after that step instead of leaving the command silently unavailable/lingering as a ghost until fppd happens to restart for an unrelated reason
    • ⚠️ Best practice - log-naming
      • log filename doesn't follow the plugin-.log convention (commonFunctions.inc.php:5: $logFile = $settings['logDirectory']."/".$pluginName.".log";).
      • Name it plugin-FPP-Plugin-Projector-Control.log (not just FPP-Plugin-Projector-Control.log), so it's recognized as this plugin's log by FPP's log viewer and namespaced against collisions with other plugins/tools
    • ⚠️ Best practice - error-reporting-suppressed
      • error_reporting(0) silences PHP errors (proj.php:7: error_reporting(0); //commented out was in file pat 2/4/2024) - a fatal error in this script now fails silently (blank output, nothing in the log) instead of surfacing where it can be debugged.
      • Remove it, or narrow it to a specific error_reporting level you actually intend to suppress
    • 💡 Optional - no-license - no LICENSE file - add one for redistribution clarity

    We know our automated checks don't always get it 100% right. Please fix whatever above does apply first - then, for anything left that doesn't apply or you think deserves an exception, comment /submit with an explanation and a maintainer will take a look.

    Once you have updated your plugin, please comment /recheck on this issue and we will automatically scan your plugin and comment the new results here.

    Want to sunset this plugin? Request Plugin Removal

  2. github-actions commented on Aug 17, 2026

    @github-actions
    ContributorAuthor

    👋 Reminder 1 - this tracking issue has had no activity in 8 days. Comment /recheck after updating your plugin, or /submit if you disagree with the findings.

    Want to sunset this plugin instead? Submit a removal request at https://falconchristmas.github.io/fpp-data/submit_remove_plugin/

  3. darylc commented on Aug 23, 2026

    @darylc
    Contributor

    /recheck

  4. github-actions commented on Aug 23, 2026

    @github-actions
    ContributorAuthor

    FPP-Plugin-Projector-Control - FPP 10 readiness

    Plugin name: Projector Control
    Repo: https://github.com/FalconChristmas/FPP-Plugin-Projector-Control
    Maintainer: FalconChristmas org (org mentions don't reliably notify anyone). Confirmed committers: darylc, dkulp, patdelaney, Poporacer (not @-mentioned automatically)

    📢 FPP's plugin guidelines and submission process have been updated - see the Plugin Guidelines for what's expected of a listed plugin. Adding another plugin? Start at Submit a plugin.

    🔄 As part of this new process, in the lead up to each new version release we will create a GitHub issue like this one and ask that you review compatibility of your plugin with the new version and outline any new best practices for plugins. Please review this information and update your plugin accordingly.

    🧪 Get your plugin ready for FPP 10

    FPP 10.0 beta3 has been released - FPP 10 full release is due shortly. Please test and update your plugin against beta3, available at https://github.com/FalconChristmas/fpp/releases/tag/10.0-beta3.

    ✅ Compatibility

    A versions[] entry already declares FPP 10 support.

    Areas of concern / optimisation

    • 🛑 Blocker - world-writable
      • loosens permissions to world-writable (fpp_install.sh:4: /usr/bin/sudo /bin/chmod a+w /dev/tty*) - since install/hooks already run as root, and the fpp runtime user is already in the dialout/tty/gpio groups that own these device nodes, there's no need to open the device to everyone - either drop the chmod entirely (group access already covers it) or scope it to the group, e.g. chmod 660
    • ⚠️ Best practice - stale-issues-prs
    • ⚠️ Best practice - destructive-no-csrf
      • destructive action with no method/CSRF guard (functions.inc.php:141: if (unlink($file)) {) - if this runs on a plain page load (not just internal cleanup after writing a replacement file, or stopping a process this same request started), it's reachable via a plain GET request with no confirmation.
      • Require $_SERVER['REQUEST_METHOD'] === 'POST' (or check a $_POST field) before running it if so
    • ⚠️ Best practice - device-path-no-allowlist
      • device path built from a variable with no allow-list check (proj.php:52: $SERIAL_DEVICE="/dev/".$DEVICE;) - if that variable traces back to request data (not just an admin-configured setting), a value like ../../etc/passwd makes this open an arbitrary path instead of a serial device.
      • Validate it against an allow-list pattern first, e.g. ^tty(USB|ACM|AMA)\d+$
    • ⚠️ Best practice - sudo
      • uses sudo in a script (fpp_install.sh:4: /usr/bin/sudo /bin/chmod a+w /dev/tty*) - install/hooks already run as root.
      • Remove the sudo call and run the command directly, e.g. /usr/bin//bin/chmod a+w /dev/tty*
    • ⚠️ Best practice - no-set-e
      • fpp_install.sh has no 'set -e' (or || exit) - without it, bash keeps running the rest of the script even after a command fails, so if an earlier step errors out (e.g. a dependency install fails), later steps still run against that broken state and the plugin ends up half-installed with no visible error.
      • Add set -e (or set -euo pipefail) as the first line after the shebang so the script stops immediately on the first failure instead
    • ⚠️ Best practice - no-restart-flag
      • registers command type(s) via commands/descriptions.json but doesn't request an fppd restart at every lifecycle point that needs one - uninstall: fpp_uninstall.sh present, no restart/reboot flag.
      • fppd only reads commands/descriptions.json and loads a native plugin's .so once, at its own startup (PluginManager::loadUserPlugins(), called once from fppd.cpp) - never again while running, and never in response to a plugin install/upgrade/uninstall.
      • Each lifecycle point runs independently (a plugin-only update runs fpp_upgrade.sh INSTEAD of fpp_install.sh when one exists; uninstall runs fpp_uninstall.sh then unconditionally deletes the plugin directory, so that script is the only code that ever runs before removal), so the flag has to be set independently in each one this plugin actually has/needs - fixing it in one script does not cover the others.
      • Add source ${FPPDIR}/scripts/common; setSetting restartFlag 1 to each script listed above (creating fpp_install.sh/fpp_uninstall.sh if missing - only fpp_upgrade.sh is optional, and only needs it if you already have one) so the Plugin Manager's restart banner appears right after that step instead of leaving the command silently unavailable/lingering as a ghost until fppd happens to restart for an unrelated reason
    • ⚠️ Best practice - log-naming
      • log filename doesn't follow the plugin-.log convention (commonFunctions.inc.php:5: $logFile = $settings['logDirectory']."/".$pluginName.".log";).
      • Name it plugin-FPP-Plugin-Projector-Control.log (not just FPP-Plugin-Projector-Control.log), so it's recognized as this plugin's log by FPP's log viewer and namespaced against collisions with other plugins/tools
    • ⚠️ Best practice - error-reporting-suppressed
      • error_reporting(0) silences PHP errors (proj.php:7: error_reporting(0); //commented out was in file pat 2/4/2024) - a fatal error in this script now fails silently (blank output, nothing in the log) instead of surfacing where it can be debugged.
      • Remove it, or narrow it to a specific error_reporting level you actually intend to suppress
    • 💡 Optional - no-license - no LICENSE file - add one for redistribution clarity

    We know our automated checks don't always get it 100% right. Please fix whatever above does apply first - then, for anything left that doesn't apply or you think deserves an exception, comment /submit with an explanation and a maintainer will take a look.

    Once you have updated your plugin, please comment /recheck on this issue and we will automatically scan your plugin and comment the new results here.

    Want to sunset this plugin? Request Plugin Removal

  5. darylc commented on Aug 24, 2026

    @darylc
    Contributor

    @Poporacer Are you planning to fix the plugin?

  6. Poporacer commented on Aug 24, 2026

    @Poporacer
    Contributor

    @patdelaney I think this is actually your plugin, I only made minor fixes, updates.

  7. github-actions commented on Aug 25, 2026

    @github-actions
    ContributorAuthor

    👋 Reminder 2 - this tracking issue has had no activity in 16 days. Comment /recheck after updating your plugin, or /submit if you disagree with the findings.

    Want to sunset this plugin instead? Submit a removal request at https://falconchristmas.github.io/fpp-data/submit_remove_plugin/

  8. github-actions commented on Sep 2, 2026

    @github-actions
    ContributorAuthor

    👋 Reminder 3 - this tracking issue has had no activity in 24 days. Comment /recheck after updating your plugin, or /submit if you disagree with the findings.

    Want to sunset this plugin instead? Submit a removal request at https://falconchristmas.github.io/fpp-data/submit_remove_plugin/

  9. github-actions commented on Sep 10, 2026

    @github-actions
    ContributorAuthor

    👋 Reminder 4 - this tracking issue has had no activity in 32 days. Comment /recheck after updating your plugin, or /submit if you disagree with the findings.

    Want to sunset this plugin instead? Submit a removal request at https://falconchristmas.github.io/fpp-data/submit_remove_plugin/

    ⚠️ For fpp-data-ci maintainers: no response after 4 reminders - consider trying to contact the plugin author some other way.

  10. darylc commented on Sep 13, 2026

    @darylc
    Contributor

    /recheck

  11. github-actions commented on Sep 13, 2026

    @github-actions
    ContributorAuthor

    FPP-Plugin-Projector-Control - FPP 10 readiness

    Plugin name: Projector Control
    Repo: https://github.com/FalconChristmas/FPP-Plugin-Projector-Control
    Maintainer: FalconChristmas org (org mentions don't reliably notify anyone). Confirmed committers: darylc, dkulp, patdelaney, Poporacer (not @-mentioned automatically)

    📢 FPP's plugin guidelines and submission process have been updated - see the Plugin Guidelines for what's expected of a listed plugin. Adding another plugin? Start at Submit a plugin.

    🔄 As part of this new process, in the lead up to each new version release we will create a GitHub issue like this one and ask that you review compatibility of your plugin with the new version and outline any new best practices for plugins. Please review this information and update your plugin accordingly.

    🧪 Get your plugin ready for FPP 10

    FPP 10.0 beta3 has been released - FPP 10 full release is due shortly. Please test and update your plugin against beta3, available at https://github.com/FalconChristmas/fpp/releases/tag/10.0-beta3.

    ✅ Compatibility

    A versions[] entry already declares FPP 10 support.

    Areas of concern / optimisation

    • 🛑 Blocker - schema
      • pluginInfo.json fails schema at (root): Additional properties are not allowed ('privacy' was unexpected)
    • 🛑 Blocker - world-writable
      • loosens permissions to world-writable (fpp_install.sh:4: /usr/bin/sudo /bin/chmod a+w /dev/tty*) - since install/hooks already run as root, and the fpp runtime user is already in the dialout/tty/gpio groups that own these device nodes, there's no need to open the device to everyone - either drop the chmod entirely (group access already covers it) or scope it to the group, e.g. chmod 660
    • ⚠️ Best practice - stale-issues-prs
    • ⚠️ Best practice - destructive-no-csrf
      • destructive action with no method/CSRF guard (functions.inc.php:141: if (unlink($file)) {) - if this runs on a plain page load (not just internal cleanup after writing a replacement file, or stopping a process this same request started), it's reachable via a plain GET request with no confirmation.
      • Require $_SERVER['REQUEST_METHOD'] === 'POST' (or check a $_POST field) before running it if so
    • ⚠️ Best practice - device-path-no-allowlist
      • device path built from a variable with no allow-list check (proj.php:52: $SERIAL_DEVICE="/dev/".$DEVICE;) - if that variable traces back to request data (not just an admin-configured setting), a value like ../../etc/passwd makes this open an arbitrary path instead of a serial device.
      • Validate it against an allow-list pattern first, e.g. ^tty(USB|ACM|AMA)\d+$
    • ⚠️ Best practice - sudo
      • uses sudo in a script (fpp_install.sh:4: /usr/bin/sudo /bin/chmod a+w /dev/tty*) - install/hooks already run as root.
      • Remove the sudo call and run the command directly, e.g. /usr/bin//bin/chmod a+w /dev/tty*
    • ⚠️ Best practice - no-set-e
      • fpp_install.sh has no 'set -e' (or || exit) - without it, bash keeps running the rest of the script even after a command fails, so if an earlier step errors out (e.g. a dependency install fails), later steps still run against that broken state and the plugin ends up half-installed with no visible error.
      • Add set -e (or set -euo pipefail) as the first line after the shebang so the script stops immediately on the first failure instead
    • ⚠️ Best practice - no-restart-flag
      • registers command type(s) via commands/descriptions.json but doesn't request an fppd restart at every lifecycle point that needs one - uninstall: fpp_uninstall.sh present, no restart/reboot flag.
      • fppd only reads commands/descriptions.json and loads a native plugin's .so once, at its own startup (PluginManager::loadUserPlugins(), called once from fppd.cpp) - never again while running, and never in response to a plugin install/upgrade/uninstall.
      • Each lifecycle point runs independently (a plugin-only update runs fpp_upgrade.sh INSTEAD of fpp_install.sh when one exists; uninstall runs fpp_uninstall.sh then unconditionally deletes the plugin directory, so that script is the only code that ever runs before removal), so the flag has to be set independently in each one this plugin actually has/needs - fixing it in one script does not cover the others.
      • Add source ${FPPDIR}/scripts/common; setSetting restartFlag 1 to each script listed above (creating fpp_install.sh/fpp_uninstall.sh if missing - only fpp_upgrade.sh is optional, and only needs it if you already have one) so the Plugin Manager's restart banner appears right after that step instead of leaving the command silently unavailable/lingering as a ghost until fppd happens to restart for an unrelated reason
    • ⚠️ Best practice - log-naming
      • log filename doesn't follow the plugin-.log convention (commonFunctions.inc.php:5: $logFile = $settings['logDirectory']."/".$pluginName.".log";).
      • Name it plugin-FPP-Plugin-Projector-Control.log (not just FPP-Plugin-Projector-Control.log), so it's recognized as this plugin's log by FPP's log viewer and namespaced against collisions with other plugins/tools
    • ⚠️ Best practice - error-reporting-suppressed
      • error_reporting(0) silences PHP errors (proj.php:7: error_reporting(0); //commented out was in file pat 2/4/2024) - a fatal error in this script now fails silently (blank output, nothing in the log) instead of surfacing where it can be debugged.
      • Remove it, or narrow it to a specific error_reporting level you actually intend to suppress
    • 💡 Optional - no-license - no LICENSE file - add one for redistribution clarity

    We know our automated checks don't always get it 100% right. Please fix whatever above does apply first - then, for anything left that doesn't apply or you think deserves an exception, comment /submit with an explanation and a maintainer will take a look.

    Once you have updated your plugin, please comment /recheck on this issue and we will automatically scan your plugin and comment the new results here.

    Want to sunset this plugin? Request Plugin Removal

  12. darylc commented on Sep 13, 2026

    @darylc
    Contributor

    pinged @patdelaney on this

  13. 7 remaining items

  14. github-actions commented on Sep 27, 2026

    @github-actions
    ContributorAuthor

    FPP-Plugin-Projector-Control - FPP 10 readiness

    Plugin name: Projector Control
    Repo: https://github.com/FalconChristmas/FPP-Plugin-Projector-Control
    Maintainer: FalconChristmas org (org mentions don't reliably notify anyone). Confirmed committers: darylc, dkulp, patdelaney, Poporacer (not @-mentioned automatically)

    📢 FPP's plugin guidelines and submission process have been updated - see the Plugin Guidelines for what's expected of a listed plugin. Adding another plugin? Start at Submit a plugin.

    🔄 As part of this new process, in the lead up to each new version release we will create a GitHub issue like this one and ask that you review compatibility of your plugin with the new version and outline any new best practices for plugins. Please review this information and update your plugin accordingly.

    🧪 Get your plugin ready for FPP 10

    FPP 10.0 beta3 has been released - FPP 10 full release is due shortly. Please test and update your plugin against beta3, available at https://github.com/FalconChristmas/fpp/releases/tag/10.0-beta3.

    ✅ Compatibility

    A versions[] entry already declares FPP 10 support.

    Areas of concern / optimisation

    • 🛑 Blocker - world-writable
      • loosens permissions to world-writable (fpp_install.sh:4: /usr/bin/sudo /bin/chmod a+w /dev/tty*) - since install/hooks already run as root, and the fpp runtime user is already in the dialout/tty/gpio groups that own these device nodes, there's no need to open the device to everyone - either drop the chmod entirely (group access already covers it) or scope it to the group, e.g. chmod 660
    • ⚠️ Best practice - stale-issues-prs
    • ⚠️ Best practice - destructive-no-csrf
      • destructive action with no method/CSRF guard (functions.inc.php:141: if (unlink($file)) {) - if this runs on a plain page load (not just internal cleanup after writing a replacement file, or stopping a process this same request started), it's reachable via a plain GET request with no confirmation.
      • Require $_SERVER['REQUEST_METHOD'] === 'POST' (or check a $_POST field) before running it if so
    • ⚠️ Best practice - device-path-no-allowlist
      • device path built from a variable with no allow-list check (proj.php:52: $SERIAL_DEVICE="/dev/".$DEVICE;) - if that variable traces back to request data (not just an admin-configured setting), a value like ../../etc/passwd makes this open an arbitrary path instead of a serial device.
      • Validate it against an allow-list pattern first, e.g. ^tty(USB|ACM|AMA)\d+$
    • ⚠️ Best practice - sudo
      • uses sudo in a script (fpp_install.sh:4: /usr/bin/sudo /bin/chmod a+w /dev/tty*) - install/hooks already run as root.
      • Remove the sudo call and run the command directly, e.g. /usr/bin//bin/chmod a+w /dev/tty*; if the script is also run by hand as a normal user, escalate only then: if [ "$(id -u)" -eq 0 ]; then <cmd>; else sudo <cmd>; fi
    • ⚠️ Best practice - no-set-e
      • fpp_install.sh has no set -e - without it, bash keeps running the rest of the script even after a command fails, so if an earlier step errors out (e.g. a dependency install fails), later steps still run against that broken state and the plugin ends up half-installed with no visible error. (This is not exit: exit ends the script where you put it; set -e makes every command after it end the script if that command fails.)
      • Add the line set -e directly under the #!/bin/bash shebang - before any other command - so the script stops on the first failure. (Plain set -e: -u breaks scripts that reference $SUDO and the like before sourcing /opt/fpp/scripts/common, and pipefail breaks common grep | ... idioms.) Per-command ... || exit 1 guards are an acceptable alternative
    • ⚠️ Best practice - no-restart-flag
      • registers command type(s) via commands/descriptions.json but doesn't request an fppd restart at every lifecycle point that needs one - uninstall: fpp_uninstall.sh present, no restart/reboot flag.
      • fppd only reads commands/descriptions.json and loads a native plugin's .so once, at its own startup (PluginManager::loadUserPlugins(), called once from fppd.cpp) - never again while running, and never in response to a plugin install/upgrade/uninstall.
      • Each lifecycle point runs independently (a plugin-only update runs fpp_upgrade.sh INSTEAD of fpp_install.sh when one exists; uninstall runs fpp_uninstall.sh then unconditionally deletes the plugin directory, so that script is the only code that ever runs before removal), so the flag has to be set independently in each one this plugin actually has/needs - fixing it in one script does not cover the others.
      • Add ( set +u; source "${FPPDIR:-/opt/fpp}/scripts/common" && setSetting restartFlag 1 ) || true to each script listed above (creating fpp_install.sh/fpp_uninstall.sh if missing - only fpp_upgrade.sh is optional, and only needs it if you already have one) so the Plugin Manager's restart banner appears right after that step instead of leaving the command silently unavailable/lingering as a ghost until fppd happens to restart for an unrelated reason
    • ⚠️ Best practice - log-naming
      • log filename doesn't follow the plugin-.log convention (proj.php:20: $logFile = $settings['logDirectory'] . "/".$pluginName.".log";).
      • Name it plugin-FPP-Plugin-Projector-Control.log (not just FPP-Plugin-Projector-Control.log), so it's recognized as this plugin's log by FPP's log viewer and namespaced against collisions with other plugins/tools
    • ⚠️ Best practice - privacy-closedcode-unverified
      • closedCode is false but the plugin installs code the listing check cannot read as source (fpp_install.sh:8: PERL_MM_USE_DEFAULT=1 cpan install Net::PJLink) - a package from PyPI/npm/CPAN or a fetched binary is open code only if its source is published.
      • Confirm the source of cpan package Net::PJLink is public at https://metacpan.org/pod/Net::PJLink; if any of it has no public source, set closedCode to true
    • ⚠️ Best practice - error-reporting-suppressed
      • error_reporting(0) silences PHP errors (proj.php:7: error_reporting(0); //commented out was in file pat 2/4/2024) - a fatal error in this script now fails silently (blank output, nothing in the log) instead of surfacing where it can be debugged.
      • Remove it, or narrow it to a specific error_reporting level you actually intend to suppress
    • 💡 Optional - no-license - no LICENSE file - add one for redistribution clarity
    • 💡 Optional - no-release-notes-style
      • pluginInfo.json has no releaseNotesStyle - FPP 10+'s Plugin Manager shows a Release Notes link only when this says where to get them, so users currently see nothing about what an update changes.
      • Add "releaseNotesStyle": "gitHistory" (the commits between the installed clone and the branch tip - no extra work), or "gitRelease" if you publish GitHub Releases with notes; see the releaseNotesStyle entry in pluginInfo.schema.json

    We know our automated checks don't always get it 100% right. Please fix whatever above does apply first - then, for anything left that doesn't apply or you think deserves an exception, comment /submit with an explanation and a maintainer will take a look.

    Once you have updated your plugin, please comment /recheck on this issue and we will automatically scan your plugin and comment the new results here.

    Want to sunset this plugin? Request Plugin Removal

  15. patdelaney commented on Sep 27, 2026

    @patdelaney
    Contributor

    /recheck

  16. github-actions commented on Sep 27, 2026

    @github-actions
    ContributorAuthor

    FPP-Plugin-Projector-Control - FPP 10 readiness

    Plugin name: Projector Control
    Repo: https://github.com/FalconChristmas/FPP-Plugin-Projector-Control
    Maintainer: FalconChristmas org (org mentions don't reliably notify anyone). Confirmed committers: patdelaney, darylc, dkulp, Poporacer (not @-mentioned automatically)

    📢 FPP's plugin guidelines and submission process have been updated - see the Plugin Guidelines for what's expected of a listed plugin. Adding another plugin? Start at Submit a plugin.

    🔄 As part of this new process, in the lead up to each new version release we will create a GitHub issue like this one and ask that you review compatibility of your plugin with the new version and outline any new best practices for plugins. Please review this information and update your plugin accordingly.

    🧪 Get your plugin ready for FPP 10

    FPP 10.0 beta3 has been released - FPP 10 full release is due shortly. Please test and update your plugin against beta3, available at https://github.com/FalconChristmas/fpp/releases/tag/10.0-beta3.

    ✅ Compatibility

    A versions[] entry already declares FPP 10 support.

    Areas of concern / optimisation

    • ⚠️ Best practice - stale-issues-prs
    • ⚠️ Best practice - device-path-no-allowlist
      • device path built from a variable with no allow-list check (proj.php:51: $SERIAL_DEVICE="/dev/".$DEVICE;) - if that variable traces back to request data (not just an admin-configured setting), a value like ../../etc/passwd makes this open an arbitrary path instead of a serial device.
      • Validate it against an allow-list pattern first, e.g. ^tty(USB|ACM|AMA)\d+$
    • ⚠️ Best practice - no-restart-flag
      • registers command type(s) via commands/descriptions.json but doesn't request an fppd restart at every lifecycle point that needs one - uninstall: fpp_uninstall.sh present, no restart/reboot flag.
      • fppd only reads commands/descriptions.json and loads a native plugin's .so once, at its own startup (PluginManager::loadUserPlugins(), called once from fppd.cpp) - never again while running, and never in response to a plugin install/upgrade/uninstall.
      • Each lifecycle point runs independently (a plugin-only update runs fpp_upgrade.sh INSTEAD of fpp_install.sh when one exists; uninstall runs fpp_uninstall.sh then unconditionally deletes the plugin directory, so that script is the only code that ever runs before removal), so the flag has to be set independently in each one this plugin actually has/needs - fixing it in one script does not cover the others.
      • Add ( set +u; source "${FPPDIR:-/opt/fpp}/scripts/common" && setSetting restartFlag 1 ) || true to each script listed above (creating fpp_install.sh/fpp_uninstall.sh if missing - only fpp_upgrade.sh is optional, and only needs it if you already have one) so the Plugin Manager's restart banner appears right after that step instead of leaving the command silently unavailable/lingering as a ghost until fppd happens to restart for an unrelated reason
    • ⚠️ Best practice - privacy-closedcode-unverified
      • closedCode is false but the plugin installs code the listing check cannot read as source (fpp_install.sh:9: PERL_MM_USE_DEFAULT=1 cpan install Net::PJLink) - a package from PyPI/npm/CPAN or a fetched binary is open code only if its source is published.
      • Confirm the source of cpan package Net::PJLink is public at https://metacpan.org/pod/Net::PJLink; if any of it has no public source, set closedCode to true

    We know our automated checks don't always get it 100% right. Please fix whatever above does apply first - then, for anything left that doesn't apply or you think deserves an exception, comment /submit with an explanation and a maintainer will take a look.

    Once you have updated your plugin, please comment /recheck on this issue and we will automatically scan your plugin and comment the new results here.

    Want to sunset this plugin? Request Plugin Removal

  17. patdelaney commented on Sep 27, 2026

    @patdelaney
    Contributor

    /recheck

  18. github-actions commented on Sep 27, 2026

    @github-actions
    ContributorAuthor

    FPP-Plugin-Projector-Control - FPP 10 readiness

    Plugin name: Projector Control
    Repo: https://github.com/FalconChristmas/FPP-Plugin-Projector-Control
    Maintainer: FalconChristmas org (org mentions don't reliably notify anyone). Confirmed committers: patdelaney, darylc, dkulp, Poporacer (not @-mentioned automatically)

    📢 FPP's plugin guidelines and submission process have been updated - see the Plugin Guidelines for what's expected of a listed plugin. Adding another plugin? Start at Submit a plugin.

    🔄 As part of this new process, in the lead up to each new version release we will create a GitHub issue like this one and ask that you review compatibility of your plugin with the new version and outline any new best practices for plugins. Please review this information and update your plugin accordingly.

    🧪 Get your plugin ready for FPP 10

    FPP 10.0 beta3 has been released - FPP 10 full release is due shortly. Please test and update your plugin against beta3, available at https://github.com/FalconChristmas/fpp/releases/tag/10.0-beta3.

    ✅ Compatibility

    A versions[] entry already declares FPP 10 support.

    Areas of concern / optimisation

    • ⚠️ Best practice - device-path-no-allowlist
      • device path built from a variable with no allow-list check (proj.php:51: $SERIAL_DEVICE = preg_match('/^tty[ASU][A-Z0-9]+$/', $DEVICE) ? "/dev/".$DEVICE : "";) - if that variable traces back to request data (not just an admin-configured setting), a value like ../../etc/passwd makes this open an arbitrary path instead of a serial device.
      • Validate it against an allow-list pattern first, e.g. ^tty(USB|ACM|AMA)\d+$
    • ⚠️ Best practice - no-restart-flag
      • registers command type(s) via commands/descriptions.json but doesn't request an fppd restart at every lifecycle point that needs one - uninstall: fpp_uninstall.sh present, no restart/reboot flag.
      • fppd only reads commands/descriptions.json and loads a native plugin's .so once, at its own startup (PluginManager::loadUserPlugins(), called once from fppd.cpp) - never again while running, and never in response to a plugin install/upgrade/uninstall.
      • Each lifecycle point runs independently (a plugin-only update runs fpp_upgrade.sh INSTEAD of fpp_install.sh when one exists; uninstall runs fpp_uninstall.sh then unconditionally deletes the plugin directory, so that script is the only code that ever runs before removal), so the flag has to be set independently in each one this plugin actually has/needs - fixing it in one script does not cover the others.
      • Add ( set +u; source "${FPPDIR:-/opt/fpp}/scripts/common" && setSetting restartFlag 1 ) || true to each script listed above (creating fpp_install.sh/fpp_uninstall.sh if missing - only fpp_upgrade.sh is optional, and only needs it if you already have one) so the Plugin Manager's restart banner appears right after that step instead of leaving the command silently unavailable/lingering as a ghost until fppd happens to restart for an unrelated reason
    • ⚠️ Best practice - privacy-text-length
      • 1 privacy text(s) exceed the install-dialog caps: systemChanges[0].what (141 > 120). FPP shows every word under its light - nothing is cut off - so a paragraph here makes the install dialog long.
      • Keep summary to 200 characters, sends[].what/why and collects[].what to 100, systemChanges[].what to 120; the detail goes in other
    • ⚠️ Best practice - privacy-closedcode-unverified
      • closedCode is false but the plugin installs code the listing check cannot read as source (fpp_install.sh:9: PERL_MM_USE_DEFAULT=1 cpan install Net::PJLink) - a package from PyPI/npm/CPAN or a fetched binary is open code only if its source is published.
      • Confirm the source of cpan package Net::PJLink is public at https://metacpan.org/pod/Net::PJLink; if any of it has no public source, set closedCode to true

    We know our automated checks don't always get it 100% right. Please fix whatever above does apply first - then, for anything left that doesn't apply or you think deserves an exception, comment /submit with an explanation and a maintainer will take a look.

    Once you have updated your plugin, please comment /recheck on this issue and we will automatically scan your plugin and comment the new results here.

    Want to sunset this plugin? Request Plugin Removal

  19. patdelaney commented on Sep 27, 2026

    @patdelaney
    Contributor

    /recheck

  20. github-actions commented on Sep 27, 2026

    @github-actions
    ContributorAuthor

    FPP-Plugin-Projector-Control - FPP 10 readiness

    Plugin name: Projector Control
    Repo: https://github.com/FalconChristmas/FPP-Plugin-Projector-Control
    Maintainer: FalconChristmas org (org mentions don't reliably notify anyone). Confirmed committers: patdelaney, darylc, dkulp, Poporacer (not @-mentioned automatically)

    📢 FPP's plugin guidelines and submission process have been updated - see the Plugin Guidelines for what's expected of a listed plugin. Adding another plugin? Start at Submit a plugin.

    🔄 As part of this new process, in the lead up to each new version release we will create a GitHub issue like this one and ask that you review compatibility of your plugin with the new version and outline any new best practices for plugins. Please review this information and update your plugin accordingly.

    🧪 Get your plugin ready for FPP 10

    FPP 10.0 beta3 has been released - FPP 10 full release is due shortly. Please test and update your plugin against beta3, available at https://github.com/FalconChristmas/fpp/releases/tag/10.0-beta3.

    ✅ Compatibility

    A versions[] entry already declares FPP 10 support.

    Areas of concern / optimisation

    • ⚠️ Best practice - device-path-no-allowlist
      • device path built from a variable with no allow-list check (proj.php:51: $SERIAL_DEVICE = preg_match('/^tty[ASU][A-Z0-9]+$/', $DEVICE) ? "/dev/".$DEVICE : "";) - if that variable traces back to request data (not just an admin-configured setting), a value like ../../etc/passwd makes this open an arbitrary path instead of a serial device.
      • Validate it against an allow-list pattern first, e.g. ^tty(USB|ACM|AMA)\d+$
    • ⚠️ Best practice - no-restart-flag
      • registers command type(s) via commands/descriptions.json but doesn't request an fppd restart at every lifecycle point that needs one - uninstall: fpp_uninstall.sh present, no restart/reboot flag.
      • fppd only reads commands/descriptions.json and loads a native plugin's .so once, at its own startup (PluginManager::loadUserPlugins(), called once from fppd.cpp) - never again while running, and never in response to a plugin install/upgrade/uninstall.
      • Each lifecycle point runs independently (a plugin-only update runs fpp_upgrade.sh INSTEAD of fpp_install.sh when one exists; uninstall runs fpp_uninstall.sh then unconditionally deletes the plugin directory, so that script is the only code that ever runs before removal), so the flag has to be set independently in each one this plugin actually has/needs - fixing it in one script does not cover the others.
      • Add ( set +u; source "${FPPDIR:-/opt/fpp}/scripts/common" && setSetting restartFlag 1 ) || true to each script listed above (creating fpp_install.sh/fpp_uninstall.sh if missing - only fpp_upgrade.sh is optional, and only needs it if you already have one) so the Plugin Manager's restart banner appears right after that step instead of leaving the command silently unavailable/lingering as a ghost until fppd happens to restart for an unrelated reason
    • ⚠️ Best practice - privacy-text-length
      • 1 privacy text(s) exceed the install-dialog caps: systemChanges[0].what (141 > 120). FPP shows every word under its light - nothing is cut off - so a paragraph here makes the install dialog long.
      • Keep summary to 200 characters, sends[].what/why and collects[].what to 100, systemChanges[].what to 120; the detail goes in other
    • ⚠️ Best practice - privacy-closedcode-unverified
      • closedCode is false but the plugin installs code the listing check cannot read as source (fpp_install.sh:9: PERL_MM_USE_DEFAULT=1 cpan install Net::PJLink) - a package from PyPI/npm/CPAN or a fetched binary is open code only if its source is published.
      • Confirm the source of cpan package Net::PJLink is public at https://metacpan.org/pod/Net::PJLink; if any of it has no public source, set closedCode to true

    We know our automated checks don't always get it 100% right. Please fix whatever above does apply first - then, for anything left that doesn't apply or you think deserves an exception, comment /submit with an explanation and a maintainer will take a look.

    Once you have updated your plugin, please comment /recheck on this issue and we will automatically scan your plugin and comment the new results here.

    Want to sunset this plugin? Request Plugin Removal

  21. patdelaney commented on Sep 27, 2026

    @patdelaney
    Contributor

    @darylc I fix some of it, but the intern seems to think some of this is false positive:

    Fixed:

    • device-path-no-allowlist — the checker flagged my own inline-ternary validation as "no check." Restructured to a plain if guard clause — functionally identical, but a shape both static checkers and human readers recognize as validation-before-use.

    • privacy-text-length — systemChanges[0].what was 141 chars (cap is 120); shortened it and moved the extra detail into other.

    Not changed, same as before:

    • no-restart-flag — still a false positive; fpp_uninstall.sh already sets it via WriteSettingToFile, the checker just doesn't recognize the PHP idiom.

    • privacy-closedcode-unverified — already correct and already documented with the MetaCPAN link. This check can't verify external registries itself, so it'll likely keep flagging any CPAN/PyPI/npm dependency regardless of documentation — nothing further to fix in code.

  22. patdelaney commented on Sep 29, 2026

    @patdelaney
    Contributor

    @darylc what is the next step here

  23. github-actions commented on Oct 4, 2026

    @github-actions
    ContributorAuthor

    👋 Reminder 7 - this tracking issue has had no activity in 56 days. Comment /recheck after updating your plugin, or /submit if you disagree with the findings.

    Want to sunset this plugin instead? Submit a removal request at https://falconchristmas.github.io/fpp-data/submit_remove_plugin/

  24. darylc commented on Oct 4, 2026

    @darylc
    Contributor

    /recheck

  25. github-actions commented on Oct 4, 2026

    @github-actions
    ContributorAuthor

    FPP-Plugin-Projector-Control - FPP 10 readiness

    Plugin name: Projector Control
    Repo: https://github.com/FalconChristmas/FPP-Plugin-Projector-Control
    Maintainer: FalconChristmas org (org mentions don't reliably notify anyone). Confirmed committers: darylc, patdelaney, dkulp, Poporacer (not @-mentioned automatically)

    📢 FPP's plugin guidelines and submission process have been updated - see the Plugin Guidelines for what's expected of a listed plugin. Adding another plugin? Start at Submit a plugin.

    🔄 As part of this new process, in the lead up to each new version release we will create a GitHub issue like this one and ask that you review compatibility of your plugin with the new version and outline any new best practices for plugins. Please review this information and update your plugin accordingly.

    🧪 Get your plugin ready for FPP 10

    FPP 10.0 beta3 has been released - FPP 10 full release is due shortly. Please test and update your plugin against beta3, available at https://github.com/FalconChristmas/fpp/releases/tag/10.0-beta3.

    ✅ Compatibility

    A versions[] entry already declares FPP 10 support.

    Areas of concern / optimisation

    • ⚠️ Best practice - device-path-no-allowlist
      • device path built from a variable with no allow-list check (proj.php:53: $SERIAL_DEVICE = "/dev/".$DEVICE;) - if that variable traces back to request data (not just an admin-configured setting), a value like ../../etc/passwd makes this open an arbitrary path instead of a serial device.
      • Validate it against an allow-list pattern first, e.g. ^tty(USB|ACM|AMA)\d+$
    • ⚠️ Best practice - no-restart-flag
      • registers command type(s) via commands/descriptions.json but doesn't request an fppd restart at every lifecycle point that needs one - uninstall: fpp_uninstall.sh present, no restart/reboot flag.
      • fppd only reads commands/descriptions.json and loads a native plugin's .so once, at its own startup (PluginManager::loadUserPlugins(), called once from fppd.cpp) - never again while running, and never in response to a plugin install/upgrade/uninstall.
      • Each lifecycle point runs independently (a plugin-only update runs fpp_upgrade.sh INSTEAD of fpp_install.sh when one exists; uninstall runs fpp_uninstall.sh then unconditionally deletes the plugin directory, so that script is the only code that ever runs before removal), so the flag has to be set independently in each one this plugin actually has/needs - fixing it in one script does not cover the others.
      • Add ( set +u; source "${FPPDIR:-/opt/fpp}/scripts/common" && setSetting restartFlag 1 ) || true to each script listed above (creating fpp_install.sh/fpp_uninstall.sh if missing - only fpp_upgrade.sh is optional, and only needs it if you already have one) so the Plugin Manager's restart banner appears right after that step instead of leaving the command silently unavailable/lingering as a ghost until fppd happens to restart for an unrelated reason
    • ⚠️ Best practice - privacy-closedcode-unverified
      • closedCode is false but the plugin installs code the listing check cannot read as source (fpp_install.sh:9: PERL_MM_USE_DEFAULT=1 cpan install Net::PJLink) - a package from PyPI/npm/CPAN, a vendored package or a fetched binary is open code only if its source is published.
      • Confirm the source of cpan package Net::PJLink is public at https://metacpan.org/pod/Net::PJLink; if any of it has no public source, set closedCode to true

    We know our automated checks don't always get it 100% right. Please fix whatever above does apply first - then, for anything left that doesn't apply or you think deserves an exception, comment /submit with an explanation and a maintainer will take a look.

    Once you have updated your plugin, please comment /recheck on this issue and we will automatically scan your plugin and comment the new results here.

    Want to sunset this plugin? Request Plugin Removal

  26. darylc commented on Oct 4, 2026

    @darylc
    Contributor

    /recheck

  27. github-actions commented on Oct 4, 2026

    @github-actions
    ContributorAuthor

    FPP-Plugin-Projector-Control - FPP 10 readiness

    Plugin name: Projector Control
    Repo: https://github.com/FalconChristmas/FPP-Plugin-Projector-Control
    Maintainer: FalconChristmas org (org mentions don't reliably notify anyone). Confirmed committers: darylc, patdelaney, dkulp, Poporacer (not @-mentioned automatically)

    📢 FPP's plugin guidelines and submission process have been updated - see the Plugin Guidelines for what's expected of a listed plugin. Adding another plugin? Start at Submit a plugin.

    🔄 As part of this new process, in the lead up to each new version release we will create a GitHub issue like this one and ask that you review compatibility of your plugin with the new version and outline any new best practices for plugins. Please review this information and update your plugin accordingly.

    🧪 Get your plugin ready for FPP 10

    FPP 10.0 beta3 has been released - FPP 10 full release is due shortly. Please test and update your plugin against beta3, available at https://github.com/FalconChristmas/fpp/releases/tag/10.0-beta3.

    ✅ Compatibility

    A versions[] entry already declares FPP 10 support.

    Areas of concern / optimisation

    • ⚠️ Best practice - privacy-closedcode-unverified
      • closedCode is false but the plugin installs code the listing check cannot read as source (fpp_install.sh:9: PERL_MM_USE_DEFAULT=1 cpan install Net::PJLink) - a package from PyPI/npm/CPAN, a vendored package or a fetched binary is open code only if its source is published.
      • Confirm the source of cpan package Net::PJLink is public at https://metacpan.org/pod/Net::PJLink; if any of it has no public source, set closedCode to true

    We know our automated checks don't always get it 100% right. Please fix whatever above does apply first - then, for anything left that doesn't apply or you think deserves an exception, comment /submit with an explanation and a maintainer will take a look.

    Once you have updated your plugin, please comment /recheck on this issue and we will automatically scan your plugin and comment the new results here.

    Want to sunset this plugin? Request Plugin Removal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions