From f0e0968828f634fd9f0584a87d22a525b1838879 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 5 May 2026 12:04:24 +0000 Subject: [PATCH 1/2] feat(apps-expose): add INCLUDED_APPS allowlist mode and update README Agent-Logs-Url: https://github.com/Parallels/prlctl-scripts/sessions/53f62372-4edc-4922-a32f-d24917f6f66f Co-authored-by: alevlasu <13949219+alevlasu@users.noreply.github.com> --- apps-expose/README.md | 51 ++++++++++++++++- apps-expose/parallels_apps_expose_service.sh | 59 +++++++++++++++++--- 2 files changed, 101 insertions(+), 9 deletions(-) diff --git a/apps-expose/README.md b/apps-expose/README.md index 3a8af07..8dde024 100644 --- a/apps-expose/README.md +++ b/apps-expose/README.md @@ -55,7 +55,54 @@ This tells macOS that the background service with this label prefix is managed, ## Configuration The agent is configured via environment variables at the top of `/usr/local/bin/parallels_apps_expose_service.sh`. -Default exclusions include: + +### Filter Mode + +The service supports two filter modes, controlled by the `FILTER_MODE` variable: + +| Mode | Variable Value | Behaviour | +|------|---------------|-----------| +| **Exclude** (default) | `FILTER_MODE=exclude` | Every app is exposed **except** those listed in `EXCLUDED_APPS`. | +| **Include** (allowlist) | `FILTER_MODE=include` | **Only** apps listed in `INCLUDED_APPS` are exposed. Everything else is hidden. | + +#### Using Exclude mode (default) + +Leave `FILTER_MODE` at its default value (`exclude`) and list the apps you want to **hide** in the `EXCLUDED_APPS` array: + +```bash +FILTER_MODE=exclude # default, can be omitted + +EXCLUDED_APPS=( + "Calculator" + "Camera" + "Notepad" + # … add more apps to hide +) +``` + +#### Using Include mode (allowlist) + +Set `FILTER_MODE=include` and list **only** the apps you want to **expose** in the `INCLUDED_APPS` array. All other apps will be ignored: + +```bash +FILTER_MODE=include + +INCLUDED_APPS=( + "My Corporate App" + "Another Tool" + # … only these apps will appear in the Windows Apps folder +) +``` + +> [!WARNING] +> If `FILTER_MODE=include` is set but `INCLUDED_APPS` is empty, **no apps will be exposed**. The service will log a warning at startup to help catch this misconfiguration. + +> [!NOTE] +> Both `EXCLUDED_APPS` and `INCLUDED_APPS` entries are treated as **regular expression** patterns anchored to the full app name (without the `.app` extension). Special characters such as `(`, `)`, and `.` must be escaped with a backslash — for example `"Microsoft 365 \(Office\)"`. + +### Default Excluded Applications (Exclude mode) + +The following apps are excluded by default when using `FILTER_MODE=exclude`: - Calculator - Camera - Character Map @@ -111,7 +158,7 @@ Default exclusions include: - Windows PowerShell - Windows Security -To modify exclusions, edit the `EXCLUSIONS` variable in the script. +To modify the filter mode or exclusion/inclusion lists, edit the corresponding variables in the script. ## Uninstalling diff --git a/apps-expose/parallels_apps_expose_service.sh b/apps-expose/parallels_apps_expose_service.sh index 2f426af..119f294 100755 --- a/apps-expose/parallels_apps_expose_service.sh +++ b/apps-expose/parallels_apps_expose_service.sh @@ -19,8 +19,18 @@ DEST_DIR="$SOURCE_ROOT/Windows Apps" # Poll interval in seconds : "${POLL_INTERVAL:=60}" -# Applications to exclude (grep patterns) -# Applications to exclude +# Filter mode: "exclude" (default) or "include" +# - "exclude": all apps are exposed EXCEPT those listed in EXCLUDED_APPS +# - "include": ONLY apps listed in INCLUDED_APPS are exposed +: "${FILTER_MODE:=exclude}" + +# Applications to include (used only when FILTER_MODE=include) +# Add each app as a separate line in the array. +# These are treated as Regex patterns. +INCLUDED_APPS=( +) + +# Applications to exclude (used only when FILTER_MODE=exclude) # Add each app as a separate line in the array # These are treated as Regex patterns. EXCLUDED_APPS=( @@ -123,6 +133,40 @@ is_excluded() { return 1 # False, not excluded } +# Check if an app name matches any inclusion pattern +is_included() { + local app_name="$1" + local pattern + + # Strip .app for easier matching if present + local clean_name="${app_name%.app}" + + for pattern in "${INCLUDED_APPS[@]}"; do + local regex="^${pattern}$" + if [[ "$clean_name" =~ $regex ]]; then + return 0 # True, it is included + fi + done + return 1 # False, not included +} + +# Returns 0 (true) if the app should be exposed based on the current FILTER_MODE +should_expose() { + local app_name="$1" + if [[ "$FILTER_MODE" == "include" ]]; then + is_included "$app_name" + else + ! is_excluded "$app_name" + fi +} + +# Validate configuration at startup +validate_config() { + if [[ "$FILTER_MODE" == "include" && ${#INCLUDED_APPS[@]} -eq 0 ]]; then + log "Warning: FILTER_MODE is 'include' but INCLUDED_APPS is empty. No apps will be exposed. Add entries to INCLUDED_APPS or switch to FILTER_MODE=exclude." + fi +} + # ============================================================================== # Core Logic # ============================================================================== @@ -145,9 +189,9 @@ sync_apps() { if [[ -L "$link" ]]; then link_name=$(basename "$link") - # Check 1: Is it excluded? - if is_excluded "$link_name"; then - log "Removing excluded link: $link_name" + # Check 1: Should it no longer be exposed? + if ! should_expose "$link_name"; then + log "Removing link (not eligible in current mode): $link_name" rm "$link" changed=1 continue @@ -176,8 +220,8 @@ sync_apps() { app_name=$(basename "$app_path") - # Check Exclusions using helper function - if is_excluded "$app_name"; then + # Check if app should be exposed based on current filter mode + if ! should_expose "$app_name"; then continue fi @@ -338,6 +382,7 @@ EOF # ============================================================================== log "Agent started. Monitoring $SOURCE_ROOT" +validate_config ensure_dest_dir FIRST_RUN=1 From 515b14ad40ce1a366bf761ea7bc6856c57b83e93 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 5 May 2026 12:06:45 +0000 Subject: [PATCH 2/2] feat(apps-expose): add Power BI Desktop and Excel to INCLUDED_APPS examples Agent-Logs-Url: https://github.com/Parallels/prlctl-scripts/sessions/90ca7327-a69d-4599-b6ad-e63ac3c5a08a Co-authored-by: alevlasu <13949219+alevlasu@users.noreply.github.com> --- apps-expose/README.md | 4 ++-- apps-expose/parallels_apps_expose_service.sh | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps-expose/README.md b/apps-expose/README.md index 8dde024..36e89d3 100644 --- a/apps-expose/README.md +++ b/apps-expose/README.md @@ -88,8 +88,8 @@ Set `FILTER_MODE=include` and list **only** the apps you want to **expose** in t FILTER_MODE=include INCLUDED_APPS=( - "My Corporate App" - "Another Tool" + "Power BI Desktop" + "Excel" # … only these apps will appear in the Windows Apps folder ) ``` diff --git a/apps-expose/parallels_apps_expose_service.sh b/apps-expose/parallels_apps_expose_service.sh index 119f294..14d1c64 100755 --- a/apps-expose/parallels_apps_expose_service.sh +++ b/apps-expose/parallels_apps_expose_service.sh @@ -28,6 +28,8 @@ DEST_DIR="$SOURCE_ROOT/Windows Apps" # Add each app as a separate line in the array. # These are treated as Regex patterns. INCLUDED_APPS=( + # "Power BI Desktop" + # "Excel" ) # Applications to exclude (used only when FILTER_MODE=exclude)