Skip to content

Commit 3fe2ba4

Browse files
committed
Update browser search skill to support Chromium
Signed-off-by: Marcus Crane <marcus@utf9k.net>
1 parent 739c387 commit 3fe2ba4

3 files changed

Lines changed: 150 additions & 82 deletions

File tree

.chezmoiignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ docs
88
**/*.md
99
.claude/*.md
1010
!.claude/CLAUDE.md
11+
!.claude/skills/**/SKILL.md
1112
setup-site.sh
1213
renovate.json
1314
node_modules
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
---
2+
name: browser-history
3+
description: Search the user's browsing history (Firefox or any Chromium-based browser — Chrome, Vivaldi, Brave, Edge, Arc, Chromium) by keyword, URL, or time. Auto-detects default browser. Use when the user wants to find something they looked at, recall a link, or see what they were browsing around a specific time.
4+
argument-hint: [search term or question] [--browser=firefox|chrome|vivaldi|brave|edge|arc|chromium]
5+
allowed-tools: Bash, Read
6+
---
7+
8+
# Browser History Search
9+
10+
Help the user find pages from their browsing history. Auto-detect the default browser and query the right database. If the user explicitly names a browser (`--browser=firefox`, "search Firefox for…"), honour that override — useful when they're not sure which browser they were in.
11+
12+
## Step 1: Detect the default browser
13+
14+
Run this once at the start to get the engine and DB path. macOS reads LaunchServices; Linux uses xdg-settings.
15+
16+
```bash
17+
detect_browser() {
18+
case "$OSTYPE" in
19+
darwin*)
20+
# Avoid $N references — the skill loader strips them when rendering into context.
21+
BUNDLE=$(defaults read ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure 2>/dev/null \
22+
| grep -B1 'LSHandlerURLScheme = https;' \
23+
| head -n 1 \
24+
| sed -E 's/.*"([^"]+)".*/\1/')
25+
APPSUP="$HOME/Library/Application Support"
26+
case "$BUNDLE" in
27+
org.mozilla.firefox) ENGINE=firefox; DB="$APPSUP/Firefox/Profiles/*.default-release/places.sqlite" ;;
28+
org.mozilla.firefoxdeveloperedition) ENGINE=firefox; DB="$APPSUP/Firefox/Profiles/*.dev-edition-default/places.sqlite" ;;
29+
com.google.chrome) ENGINE=chromium; DB="$APPSUP/Google/Chrome/Default/History" ;;
30+
com.vivaldi.vivaldi) ENGINE=chromium; DB="$APPSUP/Vivaldi/Default/History" ;;
31+
com.brave.browser) ENGINE=chromium; DB="$APPSUP/BraveSoftware/Brave-Browser/Default/History" ;;
32+
com.microsoft.edgemac) ENGINE=chromium; DB="$APPSUP/Microsoft Edge/Default/History" ;;
33+
company.thebrowser.browser) ENGINE=chromium; DB="$APPSUP/Arc/User Data/Default/History" ;;
34+
org.chromium.Chromium) ENGINE=chromium; DB="$APPSUP/Chromium/Default/History" ;;
35+
*) echo "Unknown bundle ID: $BUNDLE" >&2; return 1 ;;
36+
esac
37+
;;
38+
*)
39+
DESKTOP=$(xdg-settings get default-web-browser 2>/dev/null)
40+
case "$DESKTOP" in
41+
firefox.desktop) ENGINE=firefox; DB="$HOME/.mozilla/firefox/*.default-release/places.sqlite" ;;
42+
firefox-developer-edition.desktop) ENGINE=firefox; DB="$HOME/.mozilla/firefox/*.dev-edition-default/places.sqlite" ;;
43+
google-chrome.desktop) ENGINE=chromium; DB="$HOME/.config/google-chrome/Default/History" ;;
44+
vivaldi-stable.desktop|vivaldi.desktop) ENGINE=chromium; DB="$HOME/.config/vivaldi/Default/History" ;;
45+
brave-browser.desktop) ENGINE=chromium; DB="$HOME/.config/BraveSoftware/Brave-Browser/Default/History" ;;
46+
microsoft-edge.desktop) ENGINE=chromium; DB="$HOME/.config/microsoft-edge/Default/History" ;;
47+
chromium.desktop|chromium-browser.desktop) ENGINE=chromium; DB="$HOME/.config/chromium/Default/History" ;;
48+
*) echo "Unknown default browser: $DESKTOP" >&2; return 1 ;;
49+
esac
50+
;;
51+
esac
52+
# Resolve any glob in DB (Firefox profile dirs)
53+
DB=$(ls $DB 2>/dev/null | head -1)
54+
echo "engine=$ENGINE db=$DB"
55+
}
56+
detect_browser
57+
```
58+
59+
If the user passed `--browser=NAME`, skip detection and set `ENGINE`/`DB` from the same table.
60+
61+
## Step 2: Copy the DB
62+
63+
The history DB is locked while the browser runs. Always copy first:
64+
65+
```bash
66+
cp "$DB" /tmp/history_copy.sqlite
67+
```
68+
69+
## Step 3: Query — branch on engine
70+
71+
### Firefox (`moz_places` + `moz_historyvisits`, unix-epoch µs)
72+
73+
```sql
74+
-- Search by keyword (title or URL)
75+
sqlite3 -header -column /tmp/history_copy.sqlite "
76+
SELECT datetime(v.visit_date/1000000,'unixepoch','localtime') as time,
77+
p.title, p.url
78+
FROM moz_historyvisits v JOIN moz_places p ON v.place_id=p.id
79+
WHERE p.title LIKE '%KEYWORD%' OR p.url LIKE '%KEYWORD%'
80+
ORDER BY v.visit_date DESC LIMIT 20;"
81+
82+
-- Activity around a timestamp (±30 min context window)
83+
sqlite3 -header -column /tmp/history_copy.sqlite "
84+
SELECT datetime(v.visit_date/1000000,'unixepoch','localtime') as time,
85+
p.title, p.url
86+
FROM moz_historyvisits v JOIN moz_places p ON v.place_id=p.id
87+
WHERE datetime(v.visit_date/1000000,'unixepoch','localtime')
88+
BETWEEN 'YYYY-MM-DD HH:MM' AND 'YYYY-MM-DD HH:MM'
89+
ORDER BY v.visit_date;"
90+
91+
-- Browse a specific date
92+
sqlite3 -header -column /tmp/history_copy.sqlite "
93+
SELECT datetime(v.visit_date/1000000,'unixepoch','localtime') as time,
94+
p.title, p.url
95+
FROM moz_historyvisits v JOIN moz_places p ON v.place_id=p.id
96+
WHERE date(v.visit_date/1000000,'unixepoch','localtime') = 'YYYY-MM-DD'
97+
ORDER BY v.visit_date;"
98+
```
99+
100+
### Chromium (`urls` + `visits`, WebKit-epoch µs — offset 11644473600000000)
101+
102+
```sql
103+
-- Search by keyword (title or URL)
104+
sqlite3 -header -column /tmp/history_copy.sqlite "
105+
SELECT datetime((v.visit_time - 11644473600000000)/1000000,'unixepoch','localtime') as time,
106+
u.title, u.url
107+
FROM visits v JOIN urls u ON v.url = u.id
108+
WHERE u.title LIKE '%KEYWORD%' OR u.url LIKE '%KEYWORD%'
109+
ORDER BY v.visit_time DESC LIMIT 20;"
110+
111+
-- Activity around a timestamp
112+
sqlite3 -header -column /tmp/history_copy.sqlite "
113+
SELECT datetime((v.visit_time - 11644473600000000)/1000000,'unixepoch','localtime') as time,
114+
u.title, u.url
115+
FROM visits v JOIN urls u ON v.url = u.id
116+
WHERE datetime((v.visit_time - 11644473600000000)/1000000,'unixepoch','localtime')
117+
BETWEEN 'YYYY-MM-DD HH:MM' AND 'YYYY-MM-DD HH:MM'
118+
ORDER BY v.visit_time;"
119+
120+
-- Browse a specific date
121+
sqlite3 -header -column /tmp/history_copy.sqlite "
122+
SELECT datetime((v.visit_time - 11644473600000000)/1000000,'unixepoch','localtime') as time,
123+
u.title, u.url
124+
FROM visits v JOIN urls u ON v.url = u.id
125+
WHERE date((v.visit_time - 11644473600000000)/1000000,'unixepoch','localtime') = 'YYYY-MM-DD'
126+
ORDER BY v.visit_time;"
127+
```
128+
129+
## Workflow
130+
131+
1. Detect default browser (or honour `--browser=` override). Tell the user which engine + browser you resolved to.
132+
2. Copy the DB to `/tmp/history_copy.sqlite`
133+
3. Pick the query block matching `$ENGINE`. Substitute keyword / date / time window.
134+
4. If the user is looking for something they found *near* another page, find the anchor first, note its timestamp, then query a window around it.
135+
5. Present results concisely — time, title, URL.
136+
6. If too many results, narrow with extra filters or a tighter window.
137+
7. Clean up: `rm /tmp/history_copy.sqlite`
138+
139+
## Tips
140+
141+
- Users often remember vaguely. Try multiple LIKE patterns if the first doesn't hit.
142+
- Twitter/X links often appear as both `twitter.com` and `x.com` — search both. `t.co` short URLs indicate a click-through from Twitter.
143+
- For navigation chains: Firefox has `moz_historyvisits.from_visit` → another visit row. Chromium has `visits.from_visit` → another visit row. Both join back to themselves.
144+
- If the user can't remember which browser they were in, run the query against the other engine too — pass `--browser=` to force.
145+
- Chromium profiles other than `Default` (e.g. `Profile 1`, `Profile 2`) live alongside `Default`. Firefox dev-edition uses `*.dev-edition-default` instead of `*.default-release`.
146+
147+
## User's Request
148+
149+
$ARGUMENTS

dot_claude/skills/firefox-history/SKILL.md

Lines changed: 0 additions & 82 deletions
This file was deleted.

0 commit comments

Comments
 (0)