From ca26cf24433389c07ed151c720bd37457fba633a Mon Sep 17 00:00:00 2001 From: Harrison Ravazzolo <38767391+harrisonravazzolo@users.noreply.github.com> Date: Sun, 7 Jun 2026 13:36:30 -0400 Subject: [PATCH] FMA - claude-devtools (#47018) Co-authored-by: Allen Houchins Co-authored-by: Allen Houchins <32207388+allenhouchins@users.noreply.github.com> --- .../inputs/homebrew/claude-devtools.json | 8 +++++++ ee/maintained-apps/outputs/apps.json | 7 ++++++ .../outputs/claude-devtools/darwin.json | 22 ++++++++++++++++++ .../components/icons/ClaudeDevtools.tsx | 14 +++++++++++ .../SoftwarePage/components/icons/index.ts | 2 ++ .../app-icon-claude-devtools-60x60@2x.png | Bin 0 -> 16360 bytes 6 files changed, 53 insertions(+) create mode 100644 ee/maintained-apps/inputs/homebrew/claude-devtools.json create mode 100644 ee/maintained-apps/outputs/claude-devtools/darwin.json create mode 100644 frontend/pages/SoftwarePage/components/icons/ClaudeDevtools.tsx create mode 100644 website/assets/images/app-icon-claude-devtools-60x60@2x.png diff --git a/ee/maintained-apps/inputs/homebrew/claude-devtools.json b/ee/maintained-apps/inputs/homebrew/claude-devtools.json new file mode 100644 index 0000000000..2828dff388 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/claude-devtools.json @@ -0,0 +1,8 @@ +{ + "name": "Claude DevTools", + "unique_identifier": "com.claudecode.context", + "token": "claude-devtools", + "installer_format": "dmg", + "slug": "claude-devtools/darwin", + "default_categories": ["Developer tools"] +} diff --git a/ee/maintained-apps/outputs/apps.json b/ee/maintained-apps/outputs/apps.json index 746c9c81b2..6fd0fe196a 100644 --- a/ee/maintained-apps/outputs/apps.json +++ b/ee/maintained-apps/outputs/apps.json @@ -631,6 +631,13 @@ "unique_identifier": "com.citrix.receiver.nomas", "description": "Citrix Workspace is a managed desktop virtualization solution that delivers secure access to information, apps, and content." }, + { + "name": "Claude DevTools", + "slug": "claude-devtools/darwin", + "platform": "darwin", + "unique_identifier": "com.claudecode.context", + "description": "Claude DevTools is an app to visualise and analyse Claude Code session executions." + }, { "name": "Claude", "slug": "claude/darwin", diff --git a/ee/maintained-apps/outputs/claude-devtools/darwin.json b/ee/maintained-apps/outputs/claude-devtools/darwin.json new file mode 100644 index 0000000000..6d58283bac --- /dev/null +++ b/ee/maintained-apps/outputs/claude-devtools/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "0.5.0", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.claudecode.context';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.claudecode.context' AND version_compare(bundle_short_version, '0.5.0') < 0);" + }, + "installer_url": "https://github.com/matt1398/claude-devtools/releases/download/v0.5.0/claude-devtools-0.5.0-arm64.dmg", + "install_script_ref": "5d82929a", + "uninstall_script_ref": "1166223a", + "sha256": "f37ec018a4052aa7b73e8ece741cf864bd2ee20c0e25b911211616f672bef441", + "default_categories": [ + "Developer tools" + ] + } + ], + "refs": { + "1166223a": "#!/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\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\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/claude-devtools.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/claude-devtools'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.claudecode.context'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.claudecode.context.plist'\n", + "5d82929a": "#!/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\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.claudecode.context'\nif [ -d \"$APPDIR/claude-devtools.app\" ]; then\n\tsudo mv \"$APPDIR/claude-devtools.app\" \"$TMPDIR/claude-devtools.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/claude-devtools.app\" \"$APPDIR\"\nrelaunch_application 'com.claudecode.context'\n" + } +} diff --git a/frontend/pages/SoftwarePage/components/icons/ClaudeDevtools.tsx b/frontend/pages/SoftwarePage/components/icons/ClaudeDevtools.tsx new file mode 100644 index 0000000000..5e56a368be --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/ClaudeDevtools.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const ClaudeDevtools = (props: SVGProps) => ( + + + +); +export default ClaudeDevtools; diff --git a/frontend/pages/SoftwarePage/components/icons/index.ts b/frontend/pages/SoftwarePage/components/icons/index.ts index e0c9401c9a..b534a13f40 100644 --- a/frontend/pages/SoftwarePage/components/icons/index.ts +++ b/frontend/pages/SoftwarePage/components/icons/index.ts @@ -23,6 +23,7 @@ import Cavalry from "./Cavalry"; import Charles from "./Charles"; import ChromeRemoteDesktop from "./ChromeRemoteDesktop"; import Cinc from "./Cinc"; +import ClaudeDevtools from "./ClaudeDevtools"; import ClickShare from "./ClickShare"; import Comet from "./Comet"; import ConnectFonts from "./ConnectFonts"; @@ -380,6 +381,7 @@ export const SOFTWARE_NAME_TO_ICON_MAP = { "cisco jabber": CiscoJabber, "citrix workspace": CitrixWorkspace, claude: Claude, + "claude-devtools": ClaudeDevtools, cleanmymac_5: CleanMyMac, cleanmymac: CleanMyMac, "cleanshot x": CleanShotX, diff --git a/website/assets/images/app-icon-claude-devtools-60x60@2x.png b/website/assets/images/app-icon-claude-devtools-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..de569750d750f590ec97c3e1a3c23f55ca0ea5a4 GIT binary patch literal 16360 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

SZ-Q< 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 HG7bGd%W2cy literal 0 HcmV?d00001