Skip to content
Merged
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
189 changes: 189 additions & 0 deletions .agents/scripts/profile-readme-helper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,158 @@ _get_token_totals() {
return 0
}

# --- Map bundle ID to friendly app name ---
_friendly_app_name() {
local bundle="$1"
case "$bundle" in
# System apps
com.apple.mail) echo "Mail" ;;
com.apple.finder) echo "Finder" ;;
com.apple.MobileSMS) echo "Messages" ;;
com.apple.Photos) echo "Photos" ;;
com.apple.Preview) echo "Preview" ;;
com.apple.Safari) echo "Safari" ;;
com.apple.iCal) echo "Calendar" ;;
com.apple.systempreferences) echo "System Settings" ;;
com.apple.AddressBook) echo "Contacts" ;;
com.apple.Terminal) echo "Terminal" ;;
com.apple.dt.Xcode) echo "Xcode" ;;
com.apple.Notes) echo "Notes" ;;
# Third-party apps
org.tabby) echo "Tabby" ;;
com.brave.Browser) echo "Brave Browser" ;;
com.tinyspeck.slackmacgap) echo "Slack" ;;
net.whatsapp.WhatsApp) echo "WhatsApp" ;;
org.whispersystems.signal-desktop) echo "Signal" ;;
com.spotify.client) echo "Spotify" ;;
org.mozilla.firefox) echo "Firefox" ;;
com.google.Chrome) echo "Chrome" ;;
com.microsoft.VSCode) echo "VS Code" ;;
com.canva.affinity) echo "Affinity" ;;
org.libreoffice.script) echo "LibreOffice" ;;
com.webcatalog.juli.facebook) echo "Facebook" ;;
# Brave PWAs — extract from known mappings
com.brave.Browser.app.mjoklplbddabcmpepnokjaffbmgbkkgg) echo "GitHub" ;;
com.brave.Browser.app.lodlkdfmihgonocnmddehnfgiljnadcf) echo "X" ;;
com.brave.Browser.app.agimnkijcaahngcdmfeangaknmldooml) echo "YouTube" ;;
com.brave.Browser.app.imdajkchfecmmahjodnfnpihejhejdgo) echo "Amazon" ;;
com.brave.Browser.app.ggjocahimgaohmigbfhghnlfcnjemagj) echo "Grok" ;;
com.brave.Browser.app.mmkpebkcahljniimmcipdlmdonpnlild) echo "Nextcloud Talk" ;;
com.brave.Browser.app.bkmlmojhimpoiaopgajnfcgdknkaklcc) echo "Nextcloud Talk 2" ;;
com.brave.Browser.app.ohghonlafcimfigiajnmhdklcbjlbfda) echo "LinkedIn" ;;
com.brave.Browser.app.akpamiohjfcnimfljfndmaldlcfphjmp) echo "Instagram" ;;
com.brave.Browser.app.fmpnliohjhemenmnlpbfagaolkdacoja) echo "Claude" ;;
com.brave.Browser.app.cadlkienfkclaiaibeoongdcgmdikeeg) echo "ChatGPT" ;;
com.brave.Browser.app.gogeloecmlhfmifbfchpldmjclnfoiho) echo "Search Console" ;;
com.brave.Browser.app.fbamlndehdinmdbhpcihcihhmjmmpgjn) echo "TradingView" ;;
com.brave.Browser.app.fbjnhnmfhfifmkmokgjddadhphahbkpp) echo "Spaceship" ;;
com.brave.Browser.app.mnhkaebcjjhencmpkapnbdaogjamfbcj) echo "Google Maps" ;;
com.brave.Browser.app.kpmdbogdmbfckbgdfdffkleoleokbhod) echo "Perplexity" ;;
com.brave.Browser.app.allndljdpmepdafjbbilonjhdgmlohlh) echo "X Pro" ;;
com.brave.Browser.app.*)
# Unknown Brave PWA — try to extract a readable suffix
echo "Brave PWA"
;;
*)
# Unknown — use last component of bundle ID
local short
short="${bundle##*.}"
echo "$short"
;;
esac
return 0
}

# --- Get top apps by screen time percentage (macOS only) ---
# Returns JSON array: [{"app":"Name","today_pct":N,"week_pct":N,"month_pct":N}, ...]
_get_top_apps() {
local knowledge_db="${HOME}/Library/Application Support/Knowledge/knowledgeC.db"

if [[ "$(uname -s)" != "Darwin" ]] || [[ ! -f "$knowledge_db" ]]; then
echo "[]"
return 0
fi

# Query per-app seconds for each period, output as TSV: bundle\ttoday\tweek\tmonth
local app_data
app_data=$(sqlite3 "$knowledge_db" "
SELECT
ZVALUESTRING,
COALESCE(SUM(CASE WHEN ZSTARTDATE > (strftime('%s', 'now') - 978307200
- (CAST(strftime('%H', 'now', 'localtime') AS INTEGER) * 3600
+ CAST(strftime('%M', 'now', 'localtime') AS INTEGER) * 60
+ CAST(strftime('%S', 'now', 'localtime') AS INTEGER)))
THEN ZENDDATE - ZSTARTDATE ELSE 0 END), 0) as today_secs,
COALESCE(SUM(CASE WHEN ZSTARTDATE > (strftime('%s', 'now') - 978307200 - 86400*7)
THEN ZENDDATE - ZSTARTDATE ELSE 0 END), 0) as week_secs,
COALESCE(SUM(ZENDDATE - ZSTARTDATE), 0) as month_secs
FROM ZOBJECT
WHERE ZSTREAMNAME = '/app/usage'
AND ZSTARTDATE > (strftime('%s', 'now') - 978307200 - 86400*28)
GROUP BY ZVALUESTRING
HAVING month_secs > 0;
" 2>/dev/null) || {

Choose a reason for hiding this comment

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

medium

You're suppressing stderr from the sqlite3 command by redirecting it to /dev/null. This can hide important errors, such as a corrupted database, syntax errors in the query, or sqlite3 not being available, which makes debugging difficult. It's better to allow error messages to be printed to stderr. The || { ... } construct will still correctly handle the failure and prevent the script from exiting.

Suggested change
" 2>/dev/null) || {
") || {
References
  1. Avoid using '2>/dev/null' for blanket suppression of command errors in shell scripts to ensure that authentication, syntax, or system issues remain visible for debugging.

echo "[]"
return 0
}

if [[ -z "$app_data" ]]; then
echo "[]"
return 0
fi

# Validate and sum totals for each period (reject non-integer values)
local total_today=0 total_week=0 total_month=0
while IFS='|' read -r _bundle today_s week_s month_s; do
# Skip rows with non-integer values (prevents arithmetic injection)
[[ "$today_s" =~ ^[0-9]+$ ]] || continue
[[ "$week_s" =~ ^[0-9]+$ ]] || continue
[[ "$month_s" =~ ^[0-9]+$ ]] || continue
total_today=$((total_today + today_s))
total_week=$((total_week + week_s))
total_month=$((total_month + month_s))
Comment on lines +272 to +274

Choose a reason for hiding this comment

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

security-high high

The script is vulnerable to command injection via bash arithmetic expansion. The variables today_s, week_s, and month_s are populated from the macOS Knowledge database (knowledgeC.db), which contains app bundle IDs. An attacker can influence this database by running an app with a crafted bundle ID containing a payload like |a[$(id >&2)0]. When these values are used in an arithmetic context $((...)), bash evaluates the embedded command. This could allow a malicious app to execute arbitrary commands with the privileges of the script, potentially stealing GitHub tokens or other sensitive data.

Suggested change
total_today=$((total_today + today_s))
total_week=$((total_week + week_s))
total_month=$((total_month + month_s))
[[ "$today_s" =~ ^[0-9]+$ ]] && total_today=$((total_today + today_s))
[[ "$week_s" =~ ^[0-9]+$ ]] && total_week=$((total_week + week_s))
[[ "$month_s" =~ ^[0-9]+$ ]] && total_month=$((total_month + month_s))

done <<<"$app_data"

# Build JSON array sorted by month_secs descending, top 10
# Uses jq for safe JSON construction (prevents injection from special chars)
local json_arr="[]"
local count=0
while IFS='|' read -r bundle today_s week_s month_s; do
if [[ $count -ge 10 ]]; then
break
fi

# Validate numeric fields
[[ "$today_s" =~ ^[0-9]+$ ]] || continue
[[ "$week_s" =~ ^[0-9]+$ ]] || continue
[[ "$month_s" =~ ^[0-9]+$ ]] || continue

local name
name=$(_friendly_app_name "$bundle")

# Calculate percentages (integer, rounded)
local today_pct=0 week_pct=0 month_pct=0
if [[ $total_today -gt 0 ]]; then
today_pct=$(((today_s * 100 + total_today / 2) / total_today))
fi
if [[ $total_week -gt 0 ]]; then
week_pct=$(((week_s * 100 + total_week / 2) / total_week))
fi
if [[ $total_month -gt 0 ]]; then
month_pct=$(((month_s * 100 + total_month / 2) / total_month))
Comment on lines +297 to +303

Choose a reason for hiding this comment

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

security-high high

The variables today_s, week_s, and month_s (lines 288, 291, 294) are used in arithmetic expansions without validation. These values, derived from the external Knowledge database, can be manipulated via crafted bundle IDs, posing a high-severity command injection risk. Additionally, the current manual JSON string concatenation is fragile and susceptible to issues if app names contain special characters. It is recommended to implement strict input validation for these variables and use a robust method like jq for safe JSON construction to mitigate both the command injection and JSON fragility issues.

fi

# Use jq for safe JSON construction (handles special chars in app names)
json_arr=$(echo "$json_arr" | jq --arg app "$name" \
--argjson tp "$today_pct" --argjson wp "$week_pct" --argjson mp "$month_pct" \
'. + [{app: $app, today_pct: $tp, week_pct: $wp, month_pct: $mp}]')
count=$((count + 1))
done < <(echo "$app_data" | sort -t'|' -k4 -rn)

echo "$json_arr"
return 0
}

# --- Clean model name for display ---
_clean_model_name() {
local model="$1"
Expand Down Expand Up @@ -372,6 +524,43 @@ ${model_rows}| **Total** | **${f_total_req}** | **${f_total_in}** | **${f_total_
_${f_all_tokens} total tokens processed. Cache hit rate: ${cache_pct}% -- prompt caching reduces cost by ~${cost_reduction}% vs uncached._
EOF

# Build top apps table (macOS only — requires Knowledge DB)
local top_apps_json
top_apps_json=$(_get_top_apps)

local app_count
app_count=$(echo "$top_apps_json" | jq 'length')

if [[ "$app_count" -gt 0 ]]; then
local app_rows=""
while IFS= read -r row; do
local app today_pct week_pct month_pct
app=$(echo "$row" | jq -r '.app')
today_pct=$(echo "$row" | jq -r '.today_pct')
week_pct=$(echo "$row" | jq -r '.week_pct')
month_pct=$(echo "$row" | jq -r '.month_pct')
Comment on lines +538 to +541

Choose a reason for hiding this comment

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

medium

You are calling jq four times inside a loop to extract values from a single JSON object. This is inefficient. You can consolidate these into a single jq call and use read to populate the variables. This is more performant and idiomatic.

Suggested change
app=$(echo "$row" | jq -r '.app')
today_pct=$(echo "$row" | jq -r '.today_pct')
week_pct=$(echo "$row" | jq -r '.week_pct')
month_pct=$(echo "$row" | jq -r '.month_pct')
IFS=$'\t' read -r app today_pct week_pct month_pct < <(echo "$row" | jq -r '[.app, .today_pct, .week_pct, .month_pct] | @tsv')
References
  1. Consolidate multiple 'jq' calls into a single pass where possible to improve performance and script efficiency.


# Show "--" for 0% (app not used in that period)
local today_str week_str month_str
if [[ "$today_pct" -eq 0 ]]; then today_str="--"; else today_str="${today_pct}%"; fi
if [[ "$week_pct" -eq 0 ]]; then week_str="--"; else week_str="${week_pct}%"; fi
if [[ "$month_pct" -eq 0 ]]; then month_str="--"; else month_str="${month_pct}%"; fi

app_rows="${app_rows}| ${app} | ${today_str} | ${week_str} | ${month_str} |
"
done < <(echo "$top_apps_json" | jq -c '.[]')

cat <<EOF

## Top Apps by Screen Time

| App | Today | 7 Days | 28 Days |
| --- | ---: | ---: | ---: |
${app_rows}
_Top 10 apps by foreground time share. Mac only._
EOF
fi

return 0
}

Expand Down