Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions ee/maintained-apps/inputs/homebrew/pd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "Pd",
"slug": "pd/darwin",
"unique_identifier": "org.puredata.pd.pd-gui",
"token": "pd",
"installer_format": "zip",
"default_categories": ["Developer tools"]
}
11 changes: 9 additions & 2 deletions ee/maintained-apps/outputs/apps.json
Original file line number Diff line number Diff line change
Expand Up @@ -1800,19 +1800,26 @@
"unique_identifier": "com.parallels.desktop.console",
"description": "Parallels Desktop is virtualization software."
},
{
"name": "Pd",
"slug": "pd/darwin",
"platform": "darwin",
"unique_identifier": "org.puredata.pd.pd-gui",
"description": "Pd is a visual programming language for multimedia."
},
{
"name": "pgAdmin 4",
"slug": "pgadmin4/darwin",
"platform": "darwin",
"unique_identifier": "org.pgadmin.pgadmin4",
"description": "pgAdmin4 is an administration and development platform for PostgreSQL."
"description": "pgAdmin 4 is an administration and development platform for PostgreSQL."
},
{
"name": "pgAdmin 4",
"slug": "pgadmin4/windows",
"platform": "windows",
"unique_identifier": "pgAdmin 4",
"description": "pgAdmin4 is an administration and development platform for PostgreSQL."
"description": "pgAdmin 4 is an administration and development platform for PostgreSQL."
},
{
"name": "PhpStorm",
Expand Down
22 changes: 22 additions & 0 deletions ee/maintained-apps/outputs/pd/darwin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"versions": [
{
"version": "0.56-2",
"queries": {
"exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'org.puredata.pd.pd-gui';",
"patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'org.puredata.pd.pd-gui' AND version_compare(bundle_short_version, '0.56-2') < 0);"
},
"installer_url": "https://msp.ucsd.edu/Software/pd-0.56-2.macos.zip",
"install_script_ref": "95ddeb15",
"uninstall_script_ref": "cec1f6f1",
"sha256": "6f88bf5186df7e24c23e9eca08c0fca34d906ba82614a0e321d26bcd999eaf90",
"default_categories": [
"Developer tools"
]
}
],
"refs": {
"95ddeb15": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'org.puredata.pd.pd-gui'\nif [ -d \"$APPDIR/Pd-0.56-2.app\" ]; then\n\tsudo mv \"$APPDIR/Pd-0.56-2.app\" \"$TMPDIR/Pd-0.56-2.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Pd-0.56-2.app\" \"$APPDIR\"\nrelaunch_application 'org.puredata.pd.pd-gui'\n",
"cec1f6f1": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Pd-0.56-2.app\"\ntrash $LOGGED_IN_USER '~/Library/Preferences/org.puredata.pd.pd-gui.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/org.puredata.pd.pd-gui.savedState'\n"
Comment on lines +19 to +20

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add fail-fast error handling to prevent false-success installs.

At Line 19 and Line 20, command failures in the install script can be masked (e.g., unzip/cp failure) and still return success because relaunch_application is the last command and can return 0 when the app was not previously running.

💡 Proposed hardening
 #!/bin/bash
+set -euo pipefail

 # variables
 APPDIR="/Applications/"
 TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
@@
-unzip "$INSTALLER_PATH" -d "$TMPDIR"
+unzip -o "$INSTALLER_PATH" -d "$TMPDIR"
+[[ -d "$TMPDIR/Pd-0.56-2.app" ]] || {
+  echo "Extracted app bundle not found: $TMPDIR/Pd-0.56-2.app"
+  exit 1
+}
@@
-sudo cp -R "$TMPDIR/Pd-0.56-2.app" "$APPDIR"
+sudo cp -R "$TMPDIR/Pd-0.56-2.app" "$APPDIR"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"95ddeb15": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'org.puredata.pd.pd-gui'\nif [ -d \"$APPDIR/Pd-0.56-2.app\" ]; then\n\tsudo mv \"$APPDIR/Pd-0.56-2.app\" \"$TMPDIR/Pd-0.56-2.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Pd-0.56-2.app\" \"$APPDIR\"\nrelaunch_application 'org.puredata.pd.pd-gui'\n",
"cec1f6f1": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Pd-0.56-2.app\"\ntrash $LOGGED_IN_USER '~/Library/Preferences/org.puredata.pd.pd-gui.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/org.puredata.pd.pd-gui.savedState'\n"
#!/bin/bash
set -euo pipefail
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
# functions
quit_and_track_application() {
local bundle_id="$1"
local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
local app_running
app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
if [[ "$app_running" != "true" ]]; then
eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
eval "export $var_name=0"
return
fi
# App was running, mark it for relaunch
eval "export $var_name=1"
echo "Application '$bundle_id' was running; will relaunch after installation."
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
local quit_success=false
SECONDS=0
while (( SECONDS < timeout_duration )); do
if osascript -e "tell application id \"$bundle_id\" to quit" >/dev/null 2>&1; then
if ! pgrep -f "$bundle_id" >/dev/null 2>&1; then
echo "Application '$bundle_id' quit successfully."
quit_success=true
break
fi
fi
sleep 1
done
if [[ "$quit_success" = false ]]; then
echo "Application '$bundle_id' did not quit."
fi
}
relaunch_application() {
local bundle_id="$1"
local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local was_running
# Check if the app was running before installation
eval "was_running=\$$var_name"
if [[ "$was_running" != "1" ]]; then
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
return
fi
echo "Relaunching application '$bundle_id'..."
# Launch the app in the logged-in user's GUI session. Apps launched by root
# won't register with the user's Dock/GUI, so run 'open' as the console user.
# Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
# and GUI session — 'sudo -u' alone doesn't do this, which can cause
# LSOpenURLsWithRole() failures even when 'open' exits 0.
local open_status=0
if [[ $EUID -eq 0 ]]; then
local console_uid
console_uid=$(id -u "$console_user")
/bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
else
open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
fi
if [[ $open_status -eq 0 ]]; then
echo "Application '$bundle_id' relaunched successfully."
else
echo "Failed to relaunch application '$bundle_id'."
fi
}
# extract contents
unzip -o "$INSTALLER_PATH" -d "$TMPDIR"
[[ -d "$TMPDIR/Pd-0.56-2.app" ]] || {
echo "Extracted app bundle not found: $TMPDIR/Pd-0.56-2.app"
exit 1
}
# copy to the applications folder
quit_and_track_application 'org.puredata.pd.pd-gui'
if [ -d "$APPDIR/Pd-0.56-2.app" ]; then
sudo mv "$APPDIR/Pd-0.56-2.app" "$TMPDIR/Pd-0.56-2.app.bkp"
fi
sudo cp -R "$TMPDIR/Pd-0.56-2.app" "$APPDIR"
relaunch_application 'org.puredata.pd.pd-gui'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ee/maintained-apps/outputs/pd/darwin.json` around lines 19 - 20, The script
currently can mask failures because commands like unzip and cp may fail but the
script can still exit 0 (relaunch_application is last); add fail-fast checks:
enable strict error handling at top (e.g., set -euo pipefail) or after critical
commands check their exit status and call a common error-exit helper that logs
and exits non-zero; specifically, wrap/validate the unzip and sudo cp/mv calls
(and any sudo rm -rf if relevant) so failures in those operations cause an
immediate exit with an error message; reference functions/sections: the
top-level unzip invocation, the sudo cp/mv operations around Pd-0.56-2.app, and
the relaunch_application and quit_and_track_application flow to ensure relaunch
is not relied on to surface earlier failures.

}
}
14 changes: 14 additions & 0 deletions frontend/pages/SoftwarePage/components/icons/Pd0562.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as React from "react";

import type { SVGProps } from "react";

const Pd0562 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} {...props}>
<image
width={32}
height={32}
href="data:image/png;base64,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"
/>
</svg>
);
export default Pd0562;
2 changes: 2 additions & 0 deletions frontend/pages/SoftwarePage/components/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import Notepad from "./Notepad++";
import OktaVerify from "./OktaVerify";
import Ollama from "./Ollama";
import OpenvpnConnect from "./OpenvpnConnect";
import Pd0562 from "./Pd0562";
import PowerBi from "./PowerBi";
import Plugdata from "./Plugdata";
import Prisma from "./Prisma";
Expand Down Expand Up @@ -476,6 +477,7 @@ export const SOFTWARE_NAME_TO_ICON_MAP = {
package: Package,
"parallels desktop": ParallelsDesktop,
p4v: P4V,
pd: Pd0562,
"pgadmin 4": PgAdmin4,
pgadmin4: PgAdmin4,
phpstorm: PhpStorm,
Expand Down
Binary file added website/assets/images/app-icon-pd-60x60@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading