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
4 changes: 2 additions & 2 deletions ee/maintained-apps/outputs/android-studio/darwin.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
"patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.google.android.studio' AND version_compare(bundle_short_version, '2026.1') < 0);",
"open": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps a JOIN processes p ON substr(p.path, 1, LENGTH(a.path) + 1) = concat(a.path, '/') WHERE a.bundle_identifier = 'com.google.android.studio');"
},
"installer_url": "https://edgedl.me.gvt1.com/android/studio/install/2026.1.3.7/android-studio-quail3-mac_arm.dmg",
"installer_url": "https://edgedl.me.gvt1.com/android/studio/install/2026.1.3.8/android-studio-quail3-patch1-mac_arm.dmg",
"install_script_ref": "2f5a5ada",
"uninstall_script_ref": "aa386b1a",
"sha256": "e43fb8f880a419208f821befea17eb9ec1b00c5c2a20227db29c495411c5f99d",
"sha256": "aa77ef6919b22be51566dcd79603c323f7c403fa91dc79dc413eed7f6a05c048",
Comment on lines +10 to +13

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.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 8 \
  'FMAManifestApp|runtime\.GOARCH|GOARCH|arm64|amd64|x86_64|architecture|darwin' \
  ee/maintained-apps ee/server

Repository: fleetdm/fleet

Length of output: 50370


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- candidate manifests ---'
for f in \
  ee/maintained-apps/outputs/android-studio/darwin.json \
  ee/maintained-apps/outputs/chatgpt/darwin.json
do
  if [ -f "$f" ]; then
    printf '\n%s\n' "$f"
    cat -n "$f"
  fi
done

printf '%s\n' '--- relevant symbol locations ---'
rg -n --glob '*.go' --glob '*.ts' --glob '*.tsx' --glob '*.js' \
  'FMAManifestApp|runtime\.GOARCH|GOARCH|darwin|installer_url|install_script_ref' \
  ee/maintained-apps ee/server | head -n 400

Repository: fleetdm/fleet

Length of output: 50369


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- maintained-apps files ---'
git ls-files ee/maintained-apps | rg '(^|/)(main|.*manifest|.*maintained.*app|.*darwin).*\.go$|server' | head -n 300

printf '%s\n' '--- manifest-related Go outlines ---'
while IFS= read -r f; do
  ast-grep outline "$f" 2>/dev/null | rg -i 'manifest|app|installer|platform|architecture|darwin|mac' || true
done < <(git ls-files ee/maintained-apps ee/server | rg '\.go$' | head -n 200)

Repository: fleetdm/fleet

Length of output: 3724


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- manifest model and platform derivation ---'
cat -n ee/maintained-apps/maintained_apps.go | sed -n '1,130p'

printf '%s\n' '--- maintained-app service paths ---'
cat -n ee/server/service/maintained_apps.go | sed -n '120,230p'
cat -n ee/server/service/software_installers.go | sed -n '3580,3695p'
cat -n ee/server/service/software_installers.go | sed -n '4380,4490p'

printf '%s\n' '--- architecture-related identifiers ---'
rg -n --glob '*.go' --glob '*.sql' --glob '*.json' --glob '*.yml' --glob '*.yaml' \
  'HardwareArchitecture|hardware_architecture|architecture|Architecture|arm64|amd64|x86_64|GOARCH|cpu_type|platform.*arch|arch.*platform' \
  ee server orbit | head -n 500

Repository: fleetdm/fleet

Length of output: 50369


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- installer download and maintained-app selection references ---'
rg -n --glob '*.go' \
  'InstallerURL|installer_url|MaintainedApp|maintained app|maintained_apps|SoftwareInstallerPayload|INSTALLER_PATH|Download' \
  ee/server ee/maintained-apps | head -n 700

printf '%s\n' '--- platform and architecture fields in Fleet host models ---'
rg -n --glob '*.go' --glob '*.sql' \
  'type Host struct|FleetPlatform|Platform string|Platform:|cpu|hardware|osquery.*platform|system_info|uname' \
  server ee orbit | head -n 700

Repository: fleetdm/fleet

Length of output: 50370


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- host/platform validation in installer flows ---'
rg -n -C 6 --glob '*.go' \
  'host\.Platform|FleetPlatform\(\)|installerRequiredPlatform|IsUnixLike|cpu_type|CPUType|OperatingSystem|Arch' \
  ee/server/service/software_installers.go ee/server/service/maintained_apps.go server | head -n 500

printf '%s\n' '--- maintained-app hydration and slug resolution ---'
cat -n ee/server/service/software_installers.go | sed -n '2968,3072p'
cat -n ee/server/service/software_installers.go | sed -n '3690,3778p'

Repository: fleetdm/fleet

Length of output: 47538


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
import json
from pathlib import Path

manifest_paths = [
    Path("ee/maintained-apps/outputs/android-studio/darwin.json"),
    Path("ee/maintained-apps/outputs/chatgpt/darwin.json"),
]
for path in manifest_paths:
    data = json.loads(path.read_text())
    versions = data["versions"]
    assert len(versions) == 1, (path, len(versions))
    item = versions[0]
    url = item["installer_url"]
    print(f"{path}:")
    print(f"  platform encoded by output path: {path.parent.name}")
    print(f"  installer_url: {url}")
    print(f"  architecture marker: " + (
        "arm64/arm marker present" if any(x in url.lower() for x in ("arm64", "_arm", "-arm")) else "none"
    ))
    print(f"  manifest architecture fields: " + str([
        k for k in item if any(x in k.lower() for x in ("arch", "cpu"))
    ]))

source_paths = [
    Path("ee/maintained-apps/maintained_apps.go"),
    Path("ee/server/service/software_installers.go"),
    Path("ee/server/service/maintained_apps.go"),
]
terms = ("cpu_type", "CPUType", "runtime.GOARCH", "GOARCH", "Arch", "Architecture")
for path in source_paths:
    text = path.read_text()
    print(f"{path}:")
    for term in terms:
        print(f"  {term}: {text.count(term)}")
PY

Repository: fleetdm/fleet

Length of output: 1115


Use architecture-compatible installers for Darwin hosts.

The maintained-app path validates only host.FleetPlatform() and has no CPU-architecture selection. Intel macOS hosts can receive the ARM64-only installers in both manifests. Provide universal or Intel-compatible installers, or add architecture-aware selection.

📍 Affects 2 files
  • ee/maintained-apps/outputs/android-studio/darwin.json#L10-L13 (this comment)
  • ee/maintained-apps/outputs/chatgpt/darwin.json#L10-L13
🤖 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/android-studio/darwin.json` around lines 10 - 13,
Ensure the Darwin manifests use installers compatible with each host CPU
architecture: update both ee/maintained-apps/outputs/android-studio/darwin.json
lines 10-13 and ee/maintained-apps/outputs/chatgpt/darwin.json lines 10-13 to
provide universal or Intel-compatible installers, or implement
architecture-aware selection in the maintained-app path that currently validates
only host.FleetPlatform().

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

verify() {
  local name="$1"
  local url="$2"
  local expected="$3"
  local file="$tmpdir/$name"

  curl --fail --location --retry 3 --output "$file" "$url"
  actual="$(shasum -a 256 "$file" | awk '{print $1}')"
  test "$actual" = "$expected"
}

verify android-studio \
  'https://edgedl.me.gvt1.com/android/studio/install/2026.1.3.8/android-studio-quail3-patch1-mac_arm.dmg' \
  'aa77ef6919b22be51566dcd79603c323f7c403fa91dc79dc413eed7f6a05c048'

verify chatgpt \
  'https://persistent.oaistatic.com/codex-app-prod/ChatGPT-darwin-arm64-26.803.61601.zip' \
  'd96e2fc6d3ecfd7889cfa82827f431a99540028c6a5bf551dc06e569006db600'

verify cisco-jabber \
  'https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg' \
  'bb71f8686049930033710f88698712e6aee6ed469516f3a73e48df8cecda4d61'

Repository: fleetdm/fleet

Length of output: 3951


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

for f in \
  ee/maintained-apps/outputs/android-studio/darwin.json \
  ee/maintained-apps/outputs/chatgpt/darwin.json \
  ee/maintained-apps/outputs/cisco-jabber/darwin.json
do
  echo "===== $f ====="
  cat -n "$f"
done

echo "===== related metadata and references ====="
rg -n --glob '*.json' --glob '*.yaml' --glob '*.yml' \
  'android-studio|ChatGPT-darwin|Cisco-Jabber|Install_Cisco-Jabber|2026\.1\.3\.8|26\.803\.61601|20260722023311|bundle identifier|CFBundleIdentifier' \
  ee/maintained-apps | head -300

Repository: fleetdm/fleet

Length of output: 50370


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "===== macOS artifact architecture patterns ====="
rg -n --glob 'darwin.json' \
  '"installer_url"|"version"|"bundle_identifier"' \
  ee/maintained-apps/outputs/android-studio \
  ee/maintained-apps/outputs/chatgpt \
  ee/maintained-apps/outputs/cisco-jabber \
  ee/maintained-apps/outputs | head -250

echo "===== manifest schemas and generation rules ====="
rg -n --glob '*.json' --glob '*.yaml' --glob '*.yml' \
  'sha256|installer_url|darwin|architecture|arm64|x86_64|bundle_identifier' \
  ee/maintained-apps | head -250

echo "===== artifact headers ====="
for url in \
  'https://edgedl.me.gvt1.com/android/studio/install/2026.1.3.8/android-studio-quail3-patch1-mac_arm.dmg' \
  'https://persistent.oaistatic.com/codex-app-prod/ChatGPT-darwin-arm64-26.803.61601.zip' \
  'https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg'
do
  echo "----- $url"
  curl --fail --location --silent --show-error --head "$url"
done

Repository: fleetdm/fleet

Length of output: 50369


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

verify_hash() {
  local name="$1"
  local url="$2"
  local expected="$3"
  local file="$tmpdir/$name"

  echo "===== $name ====="
  curl --fail --location --retry 3 --silent --show-error --output "$file" "$url"
  if command -v sha256sum >/dev/null 2>&1; then
    actual="$(sha256sum "$file" | awk '{print $1}')"
  else
    actual="$(openssl dgst -sha256 "$file" | awk '{print $NF}')"
  fi
  printf 'size=%s bytes\nexpected=%s\nactual=%s\n' \
    "$(wc -c < "$file")" "$expected" "$actual"
  test "$actual" = "$expected"
}

verify_hash android-studio \
  'https://edgedl.me.gvt1.com/android/studio/install/2026.1.3.8/android-studio-quail3-patch1-mac_arm.dmg' \
  'aa77ef6919b22be51566dcd79603c323f7c403fa91dc79dc413eed7f6a05c048'

verify_hash chatgpt \
  'https://persistent.oaistatic.com/codex-app-prod/ChatGPT-darwin-arm64-26.803.61601.zip' \
  'd96e2fc6d3ecfd7889cfa82827f431a99540028c6a5bf551dc06e569006db600'

verify_hash cisco-jabber \
  'https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg' \
  'bb71f8686049930033710f88698712e6aee6ed469516f3a73e48df8cecda4d61'

Repository: fleetdm/fleet

Length of output: 725


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

chatgpt_url='https://persistent.oaistatic.com/codex-app-prod/ChatGPT-darwin-arm64-26.803.61601.zip'
cisco_url='https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg'

curl --fail --location --silent --show-error --output "$tmpdir/chatgpt.zip" "$chatgpt_url"
echo "===== ChatGPT archive ====="
unzip -l "$tmpdir/chatgpt.zip" | head -80
unzip -q "$tmpdir/chatgpt.zip" -d "$tmpdir/chatgpt"
find "$tmpdir/chatgpt" -type f -name Info.plist -print -exec \
  sh -c 'plutil -p "$1" 2>/dev/null || strings "$1" | grep -E "CFBundleIdentifier|CFBundleShortVersionString|CFBundleVersion|arm64|x86_64" | head -30' sh {} \;

curl --fail --location --silent --show-error --output "$tmpdir/cisco.pkg" "$cisco_url"
echo "===== Cisco Jabber package ====="
file "$tmpdir/cisco.pkg"
if command -v xar >/dev/null 2>&1; then
  xar -tf "$tmpdir/cisco.pkg" | head -100
  xar -xf "$tmpdir/cisco.pkg" -C "$tmpdir"
  find "$tmpdir" -type f -name '*.bom' -o -name '*.plist' | head -50
fi
strings "$tmpdir/cisco.pkg" | grep -E \
  'Cisco Jabber|15\.2|CFBundleIdentifier|com\.cisco|arm64|x86_64' | head -80

Repository: fleetdm/fleet

Length of output: 6846


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

for spec in \
  'android-studio|https://edgedl.me.gvt1.com/android/studio/install/2026.1.3.8/android-studio-quail3-patch1-mac_arm.dmg|aa77ef6919b22be51566dcd79603c323f7c403fa91dc79dc413eed7f6a05c048' \
  'chatgpt|https://persistent.oaistatic.com/codex-app-prod/ChatGPT-darwin-arm64-26.803.61601.zip|d96e2fc6d3ecfd7889cfa82827f431a99540028c6a5bf551dc06e569006db600' \
  'cisco-jabber|https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg|bb71f8686049930033710f88698712e6aee6ed469516f3a73e48df8cecda4d61'
do
  IFS='|' read -r name url expected <<< "$spec"
  file="$tmpdir/$name"
  curl --fail --location --retry 3 --silent --show-error --output "$file" "$url"
  actual="$(sha256sum "$file" | awk '{print $1}')"
  printf '%s size=%s expected=%s actual=%s\n' \
    "$name" "$(wc -c < "$file")" "$expected" "$actual"
done

Repository: fleetdm/fleet

Length of output: 671


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

chatgpt_url='https://persistent.oaistatic.com/codex-app-prod/ChatGPT-darwin-arm64-26.803.61601.zip'
cisco_url='https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg'

curl --fail --location --silent --show-error --output "$tmpdir/chatgpt.zip" "$chatgpt_url"
python3 - "$tmpdir/chatgpt.zip" <<'PY'
import plistlib, sys, zipfile

with zipfile.ZipFile(sys.argv[1]) as z:
    names = z.namelist()
    plist_name = "ChatGPT.app/Contents/Info.plist"
    print("ChatGPT Info.plist present:", plist_name in names)
    if plist_name in names:
        info = plistlib.loads(z.read(plist_name))
        for key in ("CFBundleIdentifier", "CFBundleShortVersionString",
                    "CFBundleVersion", "LSMinimumSystemVersion",
                    "CFBundlePackageType"):
            print(f"{key}={info.get(key)!r}")
PY

curl --fail --location --silent --show-error --output "$tmpdir/cisco.pkg" "$cisco_url"
echo "Cisco package:"
file "$tmpdir/cisco.pkg"
if command -v xar >/dev/null 2>&1; then
  xar -tf "$tmpdir/cisco.pkg" | head -40 || true
  xar -xf "$tmpdir/cisco.pkg" -C "$tmpdir"
  find "$tmpdir" -type f \( -name '*.plist' -o -name '*.bom' \) -print
fi
strings "$tmpdir/cisco.pkg" | grep -E \
  'Cisco Jabber|15\.2|CFBundleIdentifier|com\.cisco|arm64|x86_64' | head -80 || true

Repository: fleetdm/fleet

Length of output: 402


🌐 Web query:

Android Studio 2026.1.3.8 quail3 patch1 mac_arm release version

💡 Result:

As of August 10, 2026, there is no released version of Android Studio known as 2026.1.3.8. The latest stable major version in the Quail release cycle is Android Studio Quail 3, which corresponds to version 2026.1.3 [1][2]. Android Studio Quail 3 was officially released to the stable channel on July 30, 2026 [1][2]. Android Studio versions generally follow an animal-based naming convention (e.g., Quail) and a build version scheme (e.g., 2026.1.3) [3]. Patch releases are designated by a "Patch n" suffix (e.g., 2026.1.3 Patch 1) rather than an incremented final digit in the build number [4][5][3]. You can verify the latest stable and preview releases on the official Android Studio download page or the Android Studio release notes website [4][6].

Citations:


🌐 Web query:

Cisco Jabber Mac 15.2.1 20260722023311 Install_Cisco-Jabber-Mac.pkg bundle identifier

💡 Result:

The bundle identifier for Cisco Jabber for Mac (including version 15.2.1) is com.cisco.Jabber [1][2][3]. This identifier is consistent across versions and is used for software management, deployment, and configuration tasks [2][3]. You can verify this identifier within the application's Info.plist file or by using standard macOS commands (such as mdls or codesign checks) [1][3].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

url='https://persistent.oaistatic.com/codex-app-prod/ChatGPT-darwin-arm64-26.803.61601.zip'
curl --fail --location --silent --show-error --output "$tmpdir/chatgpt.zip" "$url"

python3 - "$tmpdir/chatgpt.zip" <<'PY'
import plistlib, sys, zipfile

with zipfile.ZipFile(sys.argv[1]) as archive:
    info = plistlib.loads(archive.read("ChatGPT.app/Contents/Info.plist"))
    for key in ("CFBundleIdentifier", "CFBundleShortVersionString",
                "CFBundleVersion", "CFBundlePackageType"):
        print(f"{key}={info.get(key)!r}")
PY

Repository: fleetdm/fleet

Length of output: 281


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "===== Cisco identifier references ====="
rg -n -i --glob '*.json' --glob '*.yaml' --glob '*.yml' \
  'com\.cisco(\.|\b)|Cisco Jabber|15\.2\.1|20260722023311' \
  ee/maintained-apps | head -120

echo "===== available package/archive inspection tools ====="
for tool in xar xz zstd 7z 7zz dmg2img hdiutil file pkgutil; do
  if command -v "$tool" >/dev/null 2>&1; then
    printf '%s=%s\n' "$tool" "$(command -v "$tool")"
  else
    printf '%s=unavailable\n' "$tool"
  fi
done

echo "===== Android Studio URL and release references ====="
rg -n --glob '*.json' --glob '*.md' --glob '*.txt' \
  '2026\.1(\.3(\.8)?)?|quail3|Android Studio' . | head -160

Repository: fleetdm/fleet

Length of output: 50369


🌐 Web query:

site:androidstudio.googleblog.com "Android Studio Quail 3" "2026.1.3"

💡 Result:

As of August 10, 2026, there is no official Android Studio version identified as "2026.1.3" associated with the "Quail" release codename [1][2][3]. The "Quail" codename refers to a series of Android Studio releases that have progressed through major versions during the summer of 2026 [3]. As of August 2026, the stable release of Android Studio Quail 3 is available, having been released on July 30, 2026 [2][3]. Additionally, the Android Studio Quail 4 series is currently in the Canary channel, with version Canary 4 released on August 6, 2026 [4][5][3]. It appears the version string "2026.1.3" may be a misinterpretation of these release patterns, as Android Studio typically uses a versioning scheme based on the year, major release, and minor/patch increments (e.g., Quail 3) rather than the specific date-based format mentioned [3].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

url='https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg'
curl --fail --location --silent --show-error --range 0-2097151 \
  --output "$tmpdir/cisco.pkg.prefix" "$url"

python3 - "$tmpdir/cisco.pkg.prefix" <<'PY'
import struct, sys, zlib
from pathlib import Path

data = Path(sys.argv[1]).read_bytes()
print("prefix_bytes", len(data))
print("magic", data[:4])
if data[:4] != b"xar!":
    raise SystemExit("not an XAR package")

header_size, version, toc_compressed, toc_uncompressed = struct.unpack(">HHQQ", data[4:24])
print("header_size", header_size)
print("version", version)
print("toc_compressed", toc_compressed)
print("toc_uncompressed", toc_uncompressed)

toc_start = header_size
toc_end = toc_start + toc_compressed
toc = data[toc_start:toc_end]
for decoder in (
    lambda b: zlib.decompress(b),
    lambda b: __import__("lzma").decompress(b),
):
    try:
        decoded = decoder(toc)
        print(decoded[:20000].decode("utf-8", "replace"))
        break
    except Exception:
        pass
else:
    raise SystemExit("could not decode XAR TOC")
PY

Repository: fleetdm/fleet

Length of output: 20256


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

url='https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg'
curl --fail --location --silent --show-error --range 0-2097151 \
  --output "$tmpdir/cisco.pkg.prefix" "$url"

python3 - "$tmpdir/cisco.pkg.prefix" <<'PY'
import struct, sys, zlib
from pathlib import Path

data = Path(sys.argv[1]).read_bytes()
print("prefix_bytes", len(data))
print("magic", data[:4])
if data[:4] != b"xar!":
    raise SystemExit("not an XAR package")

header_size, version, toc_compressed, toc_uncompressed = struct.unpack(">HHQQ", data[4:24])
print("header_size", header_size)
print("version", version)
print("toc_compressed", toc_compressed)
print("toc_uncompressed", toc_uncompressed)

toc = data[header_size:header_size + toc_compressed]
for decoder in (zlib.decompress,):
    try:
        print(decoder(toc).decode("utf-8", "replace")[:20000])
        break
    except Exception:
        pass
PY

Repository: fleetdm/fleet

Length of output: 20256


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

url='https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg'
curl --fail --location --silent --show-error --range 0-2097151 \
  --output "$tmpdir/cisco.pkg.prefix" "$url"

python3 - "$tmpdir/cisco.pkg.prefix" <<'PY'
import struct, sys, zlib
import xml.etree.ElementTree as ET
from pathlib import Path

data = Path(sys.argv[1]).read_bytes()
header_size, _, toc_compressed, _ = struct.unpack(">HHQQ", data[4:24])
toc = zlib.decompress(data[header_size:header_size + toc_compressed])
root = ET.fromstring(toc)

for node in root.iter():
    text = (node.text or "").strip()
    attrs = " ".join(f"{k}={v}" for k, v in node.attrib.items())
    if text and (
        "cisco" in text.lower()
        or "jabber" in text.lower()
        or "15.2" in text
        or node.tag.endswith(("name", "type", "archived-checksum"))
    ):
        print(node.tag, attrs, repr(text[:300]))
PY

Repository: fleetdm/fleet

Length of output: 14258


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

url='https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg'
curl --fail --location --silent --show-error --range 0-2097151 \
  --output "$tmpdir/cisco.pkg.prefix" "$url"

python3 - "$tmpdir/cisco.pkg.prefix" <<'PY'
import struct, sys, zlib
import xml.etree.ElementTree as ET
from pathlib import Path

data = Path(sys.argv[1]).read_bytes()
header_size, _, toc_compressed, _ = struct.unpack(">HHQQ", data[4:24])
toc = zlib.decompress(data[header_size:header_size + toc_compressed])
root = ET.fromstring(toc)

for node in root.iter():
    text = (node.text or "").strip()
    if text and any(value in text.lower() for value in ("cisco", "jabber", "15.2")):
        print(node.tag, repr(text[:300]))
PY

Repository: fleetdm/fleet

Length of output: 387


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

url='https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg'
curl --fail --location --silent --show-error --range 0-2097151 \
  --output "$tmpdir/toc.prefix" "$url"

python3 - "$tmpdir/toc.prefix" "$tmpdir/ranges.tsv" <<'PY'
import struct, sys, zlib
import xml.etree.ElementTree as ET
from pathlib import Path

data = Path(sys.argv[1]).read_bytes()
header_size, _, toc_compressed, _ = struct.unpack(">HHQQ", data[4:24])
root = ET.fromstring(zlib.decompress(data[header_size:header_size + toc_compressed]))

def walk(node, path=()):
    name = node.find("name")
    current = path + ((name.text,) if name is not None else ())
    data_node = node.find("data")
    if current[-1:] == ("PackageInfo",) and data_node is not None:
        offset = int(data_node.findtext("offset"))
        size = int(data_node.findtext("size"))
        print("/".join(current), offset, size)
        with open(sys.argv[2], "a") as out:
            out.write(f"{offset}\t{size}\t{'/'.join(current)}\n")
    for child in node.findall("file"):
        walk(child, current)

walk(root)
PY

while IFS=$'\t' read -r offset size path; do
  end=$((offset + size - 1))
  curl --fail --location --silent --show-error --range "$offset-$end" \
    --output "$tmpdir/packageinfo.gz" "$url"
  echo "===== $path ====="
  gzip -dc "$tmpdir/packageinfo.gz" 2>/dev/null || cat "$tmpdir/packageinfo.gz"
done < "$tmpdir/ranges.tsv"

Repository: fleetdm/fleet

Length of output: 224


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
: > "$tmpdir/ranges.tsv"

url='https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg'
curl --fail --location --silent --show-error --range 0-2097151 \
  --output "$tmpdir/toc.prefix" "$url"

python3 - "$tmpdir/toc.prefix" "$tmpdir/ranges.tsv" <<'PY'
import struct, sys, zlib
import xml.etree.ElementTree as ET
from pathlib import Path

data = Path(sys.argv[1]).read_bytes()
header_size, _, toc_compressed, _ = struct.unpack(">HHQQ", data[4:24])
root = ET.fromstring(zlib.decompress(data[header_size:header_size + toc_compressed]))

def walk(node, path=()):
    name = node.find("name")
    current = path + ((name.text,) if name is not None else ())
    data_node = node.find("data")
    if current[-1:] == ("PackageInfo",) and data_node is not None:
        offset = int(data_node.findtext("offset"))
        size = int(data_node.findtext("size"))
        print("/".join(current), offset, size)
        with open(sys.argv[2], "a") as out:
            out.write(f"{offset}\t{size}\t{'/'.join(current)}\n")
    for child in node.findall("file"):
        walk(child, current)

walk(root)
PY

while IFS=$'\t' read -r offset size path; do
  end=$((offset + size - 1))
  curl --fail --location --silent --show-error --range "$offset-$end" \
    --output "$tmpdir/packageinfo.gz" "$url"
  echo "===== $path ====="
  gzip -dc "$tmpdir/packageinfo.gz" 2>/dev/null || cat "$tmpdir/packageinfo.gz"
done < "$tmpdir/ranges.tsv"

Repository: fleetdm/fleet

Length of output: 151


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
: > "$tmpdir/ranges.tsv"

url='https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg'
curl --fail --location --silent --show-error --range 0-2097151 \
  --output "$tmpdir/toc.prefix" "$url"

python3 - "$tmpdir/toc.prefix" "$tmpdir/ranges.tsv" <<'PY'
import struct, sys, zlib
import xml.etree.ElementTree as ET
from pathlib import Path

data = Path(sys.argv[1]).read_bytes()
header_size, _, toc_compressed, _ = struct.unpack(">HHQQ", data[4:24])
root = ET.fromstring(zlib.decompress(data[header_size:header_size + toc_compressed]))

for node in root.iter("file"):
    name = node.findtext("name", "")
    data_node = node.find("data")
    if name == "PackageInfo" and data_node is not None:
        offset = int(data_node.findtext("offset"))
        size = int(data_node.findtext("size"))
        print(name, offset, size)
        with open(sys.argv[2], "a") as out:
            out.write(f"{offset}\t{size}\n")
PY

while IFS=$'\t' read -r offset size; do
  end=$((offset + size - 1))
  curl --fail --location --silent --show-error --range "$offset-$end" \
    --output "$tmpdir/packageinfo.gz" "$url"
  gzip -dc "$tmpdir/packageinfo.gz" 2>/dev/null || cat "$tmpdir/packageinfo.gz"
done < "$tmpdir/ranges.tsv"

Repository: fleetdm/fleet

Length of output: 4849


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
: > "$tmpdir/ranges.tsv"

url='https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg'
curl --fail --location --silent --show-error --range 0-2097151 \
  --output "$tmpdir/toc.prefix" "$url"

python3 - "$tmpdir/toc.prefix" "$tmpdir/ranges.tsv" <<'PY'
import struct, sys, zlib
import xml.etree.ElementTree as ET
from pathlib import Path

data = Path(sys.argv[1]).read_bytes()
header_size, _, toc_compressed, _ = struct.unpack(">HHQQ", data[4:24])
root = ET.fromstring(zlib.decompress(data[header_size:header_size + toc_compressed]))

for node in root.iter("file"):
    if node.findtext("name", "") == "PackageInfo":
        data_node = node.find("data")
        if data_node is not None:
            offset = int(data_node.findtext("offset"))
            size = int(data_node.findtext("size"))
            print("PackageInfo", offset, size)
            with open(sys.argv[2], "a") as out:
                out.write(f"{offset}\t{size}\n")
PY

while IFS=$'\t' read -r offset size; do
  end=$((offset + size - 1))
  curl --fail --location --silent --show-error --range "$offset-$end" \
    --output "$tmpdir/packageinfo.gz" "$url"
  gzip -dc "$tmpdir/packageinfo.gz" 2>/dev/null || cat "$tmpdir/packageinfo.gz"
done < "$tmpdir/ranges.tsv"

Repository: fleetdm/fleet

Length of output: 4849


Align the declared bundle identifiers with the installers.

  • ee/maintained-apps/outputs/chatgpt/darwin.json: The installer declares com.openai.codex, but the manifest and install script use com.openai.chat.
  • ee/maintained-apps/outputs/cisco-jabber/darwin.json: Cisco Jabber uses com.cisco.Jabber, but the manifest and install script use com.cisco.jabber.

Update the queries and script references so Fleet can detect, upgrade, quit, and relaunch the installed applications.

📍 Affects 3 files
  • ee/maintained-apps/outputs/android-studio/darwin.json#L10-L13 (this comment)
  • ee/maintained-apps/outputs/chatgpt/darwin.json#L10-L13
  • ee/maintained-apps/outputs/cisco-jabber/darwin.json#L10-L13
🤖 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/android-studio/darwin.json` around lines 10 - 13,
Align the application bundle identifier queries and script references in
ee/maintained-apps/outputs/chatgpt/darwin.json (lines 10-13) with the
installers: use com.openai.codex instead of com.openai.chat, and update the
related manifest/install-script references. In
ee/maintained-apps/outputs/cisco-jabber/darwin.json (lines 10-13), use
com.cisco.Jabber instead of com.cisco.jabber and update the related references.
ee/maintained-apps/outputs/android-studio/darwin.json (lines 10-13) requires no
direct change.

"default_categories": [
"Developer tools"
]
Expand Down
8 changes: 4 additions & 4 deletions ee/maintained-apps/outputs/chatgpt/darwin.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"versions": [
{
"version": "26.803.41515",
"version": "26.803.61601",
"queries": {
"exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.openai.chat';",
"patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.openai.chat' AND version_compare(bundle_short_version, '26.803.41515') < 0);",
"patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.openai.chat' AND version_compare(bundle_short_version, '26.803.61601') < 0);",
"open": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps a JOIN processes p ON substr(p.path, 1, LENGTH(a.path) + 1) = concat(a.path, '/') WHERE a.bundle_identifier = 'com.openai.chat');"
},
"installer_url": "https://persistent.oaistatic.com/codex-app-prod/ChatGPT-darwin-arm64-26.803.41515.zip",
"installer_url": "https://persistent.oaistatic.com/codex-app-prod/ChatGPT-darwin-arm64-26.803.61601.zip",
"install_script_ref": "cbce2d7d",
"uninstall_script_ref": "678e6cf0",
"sha256": "8abd46bf063bc27cbadcbc2863007ac44365b13a23ede17ceaee81fb9eeaeb9a",
"sha256": "d96e2fc6d3ecfd7889cfa82827f431a99540028c6a5bf551dc06e569006db600",
"default_categories": [
"Productivity"
]
Expand Down
4 changes: 2 additions & 2 deletions ee/maintained-apps/outputs/cisco-jabber/darwin.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
"patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.cisco.jabber' AND version_compare(bundle_short_version, '15.2.1') < 0);",
"open": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps a JOIN processes p ON substr(p.path, 1, LENGTH(a.path) + 1) = concat(a.path, '/') WHERE a.bundle_identifier = 'com.cisco.jabber');"
},
"installer_url": "https://binaries.webex.com/jabberclientmac/20260122074039/Install_Cisco-Jabber-Mac.pkg",
"installer_url": "https://binaries.webex.com/jabberclientmac/20260722023311/Install_Cisco-Jabber-Mac.pkg",
"install_script_ref": "edbec29c",
"uninstall_script_ref": "fe0e9261",
"sha256": "5644700e420febc1eca304c0a0f24bcff1e64b424112e1beda025d2eb78e16de",
"sha256": "bb71f8686049930033710f88698712e6aee6ed469516f3a73e48df8cecda4d61",
"default_categories": [
"Communication"
]
Expand Down
Loading