Skip to content
Merged
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
10 changes: 10 additions & 0 deletions bin/code-notify
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ case "$COMMAND_NAME" in
source "$LIB_DIR/commands/global.sh"
handle_global_command "$@"
;;
"click-through")
[[ "$(uname -s)" != "Darwin" ]] && { error "Unknown command: $1"; echo "Try 'cn help' for usage"; exit 1; }
source "$LIB_DIR/commands/global.sh"
handle_global_command "$@"
;;
"repair-hooks")
shift
repair_legacy_hooks_command "${1:-}"
Expand All @@ -77,6 +82,11 @@ case "$COMMAND_NAME" in
source "$LIB_DIR/commands/global.sh"
handle_global_command "$@"
;;
"click-through")
[[ "$(uname -s)" != "Darwin" ]] && { error "Unknown command: $1"; echo "Try 'code-notify help' for usage"; exit 1; }
source "$LIB_DIR/commands/global.sh"
handle_global_command "$@"
;;
"repair-hooks")
shift
repair_legacy_hooks_command "${1:-}"
Expand Down
4 changes: 4 additions & 0 deletions lib/code-notify/commands/global.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ GLOBAL_CMD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$GLOBAL_CMD_DIR/../utils/voice.sh"
source "$GLOBAL_CMD_DIR/../utils/sound.sh"
source "$GLOBAL_CMD_DIR/../utils/help.sh"
source "$GLOBAL_CMD_DIR/../utils/click-through.sh"

CODE_NOTIFY_RELEASES_API="https://api.github.com/repos/mylee04/code-notify/releases/latest"

Expand Down Expand Up @@ -43,6 +44,9 @@ handle_global_command() {
"alerts")
handle_alerts_command "$@"
;;
"click-through")
handle_click_through_command "$@"
;;
"help")
show_help
;;
Expand Down
22 changes: 4 additions & 18 deletions lib/code-notify/core/notifier.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ NOTIFIER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$NOTIFIER_DIR/../utils/detect.sh"
source "$NOTIFIER_DIR/../utils/voice.sh"
source "$NOTIFIER_DIR/../utils/sound.sh"
source "$NOTIFIER_DIR/../utils/click-through-store.sh"
source "$NOTIFIER_DIR/../utils/click-through-runtime.sh"
source "$NOTIFIER_DIR/../utils/click-through-resolver.sh"

has_jq() {
command -v jq >/dev/null 2>&1
Expand Down Expand Up @@ -328,24 +331,7 @@ fi

# Get terminal bundle ID for macOS activation
get_terminal_bundle_id() {
case "${TERM_PROGRAM:-}" in
"iTerm.app") echo "com.googlecode.iterm2" ;;
"Apple_Terminal") echo "com.apple.Terminal" ;;
"vscode") echo "com.microsoft.VSCode" ;;
"WezTerm") echo "com.github.wez.wezterm" ;;
"Alacritty") echo "org.alacritty" ;;
"Hyper") echo "co.zeit.hyper" ;;
*)
# Fallback: try to detect from parent process
if [[ -n "${ITERM_SESSION_ID:-}" ]]; then
echo "com.googlecode.iterm2"
elif [[ -n "${WEZTERM_PANE:-}" ]]; then
echo "com.github.wez.wezterm"
else
echo "com.apple.Terminal"
fi
;;
esac
click_through_resolve_activation_bundle_id
}

# Function to send notification on macOS
Expand Down
96 changes: 96 additions & 0 deletions lib/code-notify/utils/click-through-resolver.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/bin/bash

# Requires click-through-store.sh and click-through-runtime.sh to be sourced first.

click_through_resolve_configured_bundle_id() {
local term_prog bundle_id

term_prog=$(click_through_get_runtime_term_program || true)
if [[ -n "$term_prog" ]]; then
bundle_id=$(click_through_lookup_config_bundle_id "$term_prog" || true)
if [[ -n "$bundle_id" ]]; then
printf '%s\n' "$bundle_id"
return 0
fi
fi

bundle_id=$(click_through_get_context_bundle_id || true)
if [[ -n "$bundle_id" ]] && click_through_lookup_config_term_program "$bundle_id" >/dev/null 2>&1; then
printf '%s\n' "$bundle_id"
return 0
fi

return 1
}

click_through_resolve_activation_bundle_id() {
local term_prog bundle_id

bundle_id=$(click_through_resolve_configured_bundle_id || true)
if [[ -n "$bundle_id" ]]; then
printf '%s\n' "$bundle_id"
return 0
fi

term_prog=$(click_through_get_runtime_term_program || true)
if [[ -n "$term_prog" ]]; then
bundle_id=$(click_through_lookup_builtin_bundle_id "$term_prog" || true)
if [[ -n "$bundle_id" ]]; then
printf '%s\n' "$bundle_id"
return 0
fi
fi

click_through_get_fallback_bundle_id
}

click_through_resolve_default_term_program() {
local bundle_id="$1"
local app_name="$2"
local term_prog

term_prog=$(click_through_get_runtime_term_program || true)
if [[ -n "$term_prog" ]]; then
printf '%s\n' "$term_prog"
return 0
fi

if [[ -n "$bundle_id" ]]; then
term_prog=$(click_through_lookup_config_term_program "$bundle_id" || true)
if [[ -n "$term_prog" ]]; then
printf '%s\n' "$term_prog"
return 0
fi

term_prog=$(click_through_lookup_builtin_term_program "$bundle_id" || true)
if [[ -n "$term_prog" ]]; then
printf '%s\n' "$term_prog"
return 0
fi
fi

click_through_normalize_term_program "$app_name"
}

click_through_find_existing_mapping_term_program() {
local bundle_id="$1"
local term_prog existing_bundle

term_prog=$(click_through_get_runtime_term_program || true)
if [[ -n "$term_prog" ]]; then
existing_bundle=$(click_through_lookup_config_bundle_id "$term_prog" || true)
if [[ "$existing_bundle" == "$bundle_id" ]]; then
printf '%s\n' "$term_prog"
return 0
fi
return 1
fi

term_prog=$(click_through_lookup_config_term_program "$bundle_id" || true)
if [[ -n "$term_prog" ]]; then
printf '%s\n' "$term_prog"
return 0
fi

return 1
}
83 changes: 83 additions & 0 deletions lib/code-notify/utils/click-through-runtime.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/bin/bash

click_through_normalize_term_program() {
local fallback="${1:-app}"
printf '%s\n' "$fallback" | tr '[:upper:]' '[:lower:]' | tr ' ' '_' | tr -cd '[:alnum:]_.-'
}

click_through_get_fallback_bundle_id() {
if [[ -n "${GHOSTTY_RESOURCES_DIR:-}" ]]; then
echo "com.mitchellh.ghostty"
elif [[ -n "${ITERM_SESSION_ID:-}" ]]; then
echo "com.googlecode.iterm2"
elif [[ -n "${WEZTERM_PANE:-}" ]]; then
echo "com.github.wez.wezterm"
else
echo "com.apple.Terminal"
fi
}

click_through_get_bundle_id() {
local app_path="$1"
/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$app_path/Contents/Info.plist" 2>/dev/null
}

click_through_detect_parent_app_path() {
local pid=$$
local parent command app_path

if [[ -n "${CODE_NOTIFY_CLICK_THROUGH_APP_PATH:-}" ]] && [[ -d "${CODE_NOTIFY_CLICK_THROUGH_APP_PATH}" ]]; then
printf '%s\n' "${CODE_NOTIFY_CLICK_THROUGH_APP_PATH}"
return 0
fi

while [[ "$pid" -gt 1 ]]; do
parent=$(ps -o ppid= -p "$pid" 2>/dev/null | tr -d ' ')
[[ -n "$parent" ]] || return 1
pid="$parent"
command=$(ps -o command= -p "$pid" 2>/dev/null || true)

if [[ "$command" == *".app/Contents/MacOS/"* ]]; then
app_path="${command%%.app/Contents/MacOS/*}.app"
if [[ "$app_path" != *"/Contents/Frameworks/"* ]] && [[ -d "$app_path" ]]; then
printf '%s\n' "$app_path"
return 0
fi
fi
done

return 1
}

click_through_get_context_bundle_id() {
local app_path bundle_id

app_path=$(click_through_detect_parent_app_path 2>/dev/null || true)
if [[ -n "$app_path" ]]; then
bundle_id=$(click_through_get_bundle_id "$app_path")
if [[ -n "$bundle_id" ]]; then
printf '%s\n' "$bundle_id"
return 0
fi
fi

if [[ -n "${__CFBundleIdentifier:-}" ]]; then
printf '%s\n' "${__CFBundleIdentifier}"
return 0
fi

return 1
}

click_through_get_runtime_term_program() {
local term_prog

for term_prog in "${TERM_PROGRAM:-}" "${TERMINAL_EMULATOR:-}" "${LC_TERMINAL:-}"; do
if [[ -n "$term_prog" ]]; then
printf '%s\n' "$term_prog"
return 0
fi
done

return 1
}
Loading
Loading