|
drwx------ 1 lukas staff 16384 11 Apr 16:34 sc drwx------ 1 lukas staff 16384 11 Apr 16:34 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ touch /Volumes/screenpipe/test.txt
touch: /Volumes/screenpipe/test.txt: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ umount /Volumes/screenpipe
umount: unmount(/Volumes/screenpipe): Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ touch /Volumes/screenpipe/test.txt
touch: /Volumes/screenpipe/test.txt: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/db.sqlite
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ scp ~/.screenpipe/db.sqlite Adm1n@[IP_ADDRESS]:/volume1/screenpipe/db.sqlite
scp: dest open "/volume1/screenpipe/db.sqlite": No such file or directory
scp: failed to upload file /Users/lukas/.screenpipe/db.sqlite to /volume1/screenpipe/db.sqlite
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ scp ~/.screenpipe/db.sqlite Adm1n@[IP_ADDRESS]:/volume1/screenpipe/
scp: dest open "/volume1/screenpipe/": No such file or directory
scp: failed to upload file /Users/lukas/.screenpipe/db.sqlite to /volume1/screenpipe/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ll
total 32
drwxr-xr-x 4 root wheel 128 11 Apr 16:35 .
drwxr-xr-x 20 root wheel 640 4 Aug 2024 ..
lrwxr-xr-x 1 root wheel 1 11 Apr 11:13 Macintosh HD -> /
drwx------ 1 lukas staff 16384 11 Apr 16:34 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $clear
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: touch:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: bad pattern: unmount(/Volumes/screenpipe):
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: touch:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: cp:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: scp:
zsh: command not found: scp:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: scp:
zsh: command not found: scp:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: total
zsh: command not found: drwxr-xr-x
zsh: command not found: drwxr-xr-x
zsh: file exists: /
zsh: command not found: drwx------
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ clear
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ scp ~/.screenpipe/db.sqlite Adm1n@[IP_ADDRESS]:/volume1/screenpipe/db.sqlite
scp: dest open "/volume1/screenpipe/db.sqlite": No such file or directory
scp: failed to upload file /Users/lukas/.screenpipe/db.sqlite to /volume1/screenpipe/db.sqlite
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ls
Macintosh HD screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ll
total 32
drwxr-xr-x 4 root wheel 128 11 Apr 16:35 .
drwxr-xr-x 20 root wheel 640 4 Aug 2024 ..
lrwxr-xr-x 1 root wheel 1 11 Apr 11:13 Macintosh HD -> /
drwx------ 1 lukas staff 16384 11 Apr 16:34 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/db.sqlite
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/Test/screenpipe/db.sqlite
cp: /Volumes/Test/screenpipe/db.sqlite: No such file or directory
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/Test/screenpipe/
cp: directory /Volumes/Test/screenpipe does not exist
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/Test/screenpipe/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/db.sqlite
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ll
total 96
drwxr-xr-x 6 root wheel 192 11 Apr 16:45 .
drwxr-xr-x 20 root wheel 640 4 Aug 2024 ..
drwx------ 1 lukas staff 16384 10 Aug 2025 Apps
lrwxr-xr-x 1 root wheel 1 11 Apr 11:13 Macintosh HD -> /
drwx------ 1 lukas staff 16384 11 Apr 15:46 Test
drwx------ 1 lukas staff 16384 11 Apr 16:47 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp -r ~/.screenpipe/pipes/ /Volumes/Test/screenpipe/pipes/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp -r ~/.screenpipe/data/data/ /Volumes/Test/screenpipe/data/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ sed 's|$HOME/.screenpipe/db.sqlite|/volume1/Test/screenpipe/db.sqlite|g' ~/screenpipe-day.sh > /volume1/Test/screenpipe/screenpipe-day.sh
zsh: no such file or directory: /volume1/Test/screenpipe/screenpipe-day.sh
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cat ~/screenpipe-day.sh
#!/bin/zsh
DB="$HOME/.screenpipe/db.sqlite"
DATE=${1:-$(date -v-1d '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo "\n⌨️ ACTIVITY TYPE PER APP (clicks / keys / switches)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo "\n🌐 BROWSER URLS VISITED"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo "\n📋 CLIPBOARD ACTIVITY"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo "\n💬 OCR TEXT SAMPLES PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-15s %s', o.app_name, SUBSTR(o.text, 1, 80))
FROM ocr_text o
JOIN frames f ON o.frame_id = f.id
WHERE date(f.timestamp) = '$DATE' AND o.app_name IS NOT NULL AND o.text != ''
GROUP BY o.app_name
ORDER BY o.app_name LIMIT 15;"
echo "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT
'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';
"
sqlite3 "$DB" "
SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';
"
sqlite3 "$DB" "
SELECT 'OCR texts: ' || COUNT(*) FROM ocr_text o JOIN frames f ON o.frame_id = f.id WHERE date(f.timestamp) = '$DATE';
"
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ curl -X POST [URL_WITH_CREDENTIALS] /Volumes $ curl -X POST [URL_WITH_CREDENTIALS] /Volumes $ curl [URL_WITH_CREDENTIALS] /Volumes $ curl -s [URL_WITH_CREDENTIALS] /Volumes $ echo "alias sp-status='curl -s [URL_WITH_CREDENTIALS] /Volumes $ sp-status
zsh: command not found: sp-status
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ source ~/.zprofile
Poetry could not find a pyproject.toml file in /Volumes or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ sp-status
zsh: command not found: sp-status
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ zp
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ls
Apps Macintosh HD Test screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cd
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ ll
total 1272
drwx------+ 89 lukas staff 2848 11 Apr 18:38 .
drwxr-xr-x 5 root admin 160 23 Aug 2024 ..
-r-------- 1 lukas staff 7 18 Nov 2021 .CFUserTextEncoding
-rw-r--r--@ 1 lukas staff 22532 11 Apr 16:46 .DS_Store
drwx------+ 2 lukas staff 64 11 Apr 11:15 .Trash
drwx------ 5 lukas staff 160 1 Nov 2021 .aws
-rw-r--r-- 1 lukas staff 341470 29 Sep 2022 .babel.json
-rw-------@ 1 lukas staff 388 25 Jul 2025 .bash_history
-rw-r--r--@ 1 lukas staff 77 9 Feb 2023 .bashrc
drwxr-xr-x 5 lukas staff 160 11 Mar 2023 .bito
drwx------@ 6 lukas staff 192 9 Apr 19:53 .cache
drwxr-xr-x 20 lukas staff 640 9 Apr 21:21 .claude
-rw------- 1 lukas staff 24973 9 Apr 21:24 .claude.json
drwxr-xr-x@ 20 lukas staff 640 12 Mar 09:12 .codeium
drwxrwxrwx@ 3 lukas staff 96 2 Mar 2023 .composer
drwx------ 16 lukas staff 512 21 May 2025 .config
drwxr-xr-x 15 lukas staff 480 23 Dec 2024 .continue
drwx------@ 3 lukas staff 96 16 Feb 19:13 .copilot
drwxr-xr-x@ 5 lukas staff 160 9 Apr 2025 .cursor
drwxr-xr-x@ 5 lukas staff 160 17 Aug 2024 .cursor-tutor
drwxr-xr-x 3 lukas staff 96 8 Sep 2024 .daytona
drwxr-xr-x@ 4 lukas staff 128 18 Feb 10:52 .devdb
drwx------ 24 lukas staff 768 9 Apr 18:24 .docker
drwx------ 15 lukas staff 480 6 Jun 2023 .dropbox
drwxr-xr-x@ 3 lukas staff 96 20 Nov 2022 .fig.dotfiles.bak
-rw-r--r-- 1 lukas staff 138 5 Mar 2022 .gauth
-rw-r--r-- 1 lukas staff 220 25 Nov 2021 .gitconfig
-rw-r--r-- 1 lukas staff 12288 25 Nov 2021 .gitconfig.swp
drwx------ 5 lukas staff 160 18 Nov 2021 .hammerspoon
drwxr-xr-x 3 lukas staff 96 21 Mar 2025 .idlerc
-rw------- 1 lukas staff 20 31 Mar 18:32 .lesshst
drwx------ 5 lukas staff 160 23 Dec 2024 .local
-rw------- 1 lukas staff 204 16 Mar 2024 .netrc
drwx------ 3 lukas staff 96 1 Nov 2021 .node-gyp
-rw------- 1 lukas staff 4 6 Feb 2024 .node_repl_history
-rw-r--r-- 1 lukas staff 17 24 Dec 2023 .notion-enhancer
drwxr-xr-x 4 lukas staff 128 12 Jul 2024 .notion-py
drwx------ 9 lukas staff 288 11 Apr 18:41 .npm
-rw------- 1 lukas staff 74 20 May 2024 .npmrc
drwx------ 32 lukas staff 1024 25 Jul 2025 .nvm
drwxr-xr-x 4 lukas staff 128 5 Aug 2023 .postman
-rw-r--r--@ 1 lukas staff 77 9 Feb 2023 .profile
-rw-------@ 1 lukas staff 3153 21 Mar 2025 .python_history
drwx------ 2 lukas staff 64 15 Nov 2021 .quicktype-vscode
drwxr-xr-x@ 8 lukas staff 256 16 Feb 08:48 .redis-insight
drwxr-xr-x 10 lukas staff 320 11 Apr 14:52 .screenpipe
UW PICO 5.09 New Buffer
[ Read 11 lines ]
^G Get Help ^O WriteOut ^R Read File ^Y Prev Pg ^K Cut Text ^C Cur Pos
^X Exit ^J Justify ^W Where is ^V Next Pg ^U UnCut Text ^T To Spell
drwxr-xr-x 4 lukas staff 128 4 Feb 09:35 .sonarlint
drwx------ 15 lukas staff 480 8 Aug 2025 .ssh
drwxr-xr-x@ 3 lukas staff 96 15 Aug 2025 .streamlit
drwx------ 6 lukas staff 192 17 Oct 2022 .swiftpm
-rw------- 1 lukas staff 12183 8 Apr 19:14 .viminfo
drwx------ 5 lukas staff 160 19 Jun 2023 .vscode
drwxr-xr-x@ 3 lukas staff 96 20 Jan 2025 .warp
drwxr-xr-x 4 lukas staff 128 29 Apr 2023 .wdm
drwxr-xr-x@ 5 lukas staff 160 26 Jan 13:03 .windsurf
drwxr-xr-x 4 lukas staff 128 24 Mar 12:03 .yarn
-rw-r--r-- 1 lukas staff 116 30 Mar 10:12 .yarnrc
-rw-r--r--@ 1 lukas staff 49518 6 Apr 14:31 .zcompdump
-rw-r--r--@ 1 lukas staff 46758 2 Nov 20:34 .zcompdump.Lukas-Kovaliks-MacBook-Pro-Jiminny.23381
-rw-r--r--@ 1 lukas staff 5641 9 Apr 20:30 .zprofile
-rw-r--r-- 1 lukas staff 1468 8 Apr 2022 .zprofile-copy
-rw-r--r--@ 1 lukas staff 2900 15 Mar 2023 .zprofile.pysave
-rw------- 1 lukas staff 1731 29 Jun 2022 .zprofile.save
-rw-r--r-- 1 lukas staff 1569 8 Apr 2022 .zprofilees
-rw------- 1 lukas staff 28812 11 Apr 18:38 .zsh_history
drwx------ 9 lukas staff 288 6 May 2025 .zsh_sessions
-rw-r--r--@ 1 lukas staff 597 11 Apr 18:44 .zshrc
drwx------@ 9 lukas staff 288 9 Apr 20:08 Applications
drwxr-xr-x@ 2 lukas staff 64 22 Oct 09:35 CascadeProjects
drwxr-xr-x 4 lukas staff 128 27 Oct 09:24 DEV
drwx------@ 10 lukas staff 320 11 Apr 18:31 Desktop
drwx------@ 7 lukas staff 224 26 Mar 14:40 Documents
drwx------@ 41 lukas staff 1312 8 Apr 20:46 Downloads
drwxr-xr-x@ 4 lukas staff 128 17 Mar 20:27 Keychron_Screen
drwx------@ 112 lukas staff 3584 2 Dec 09:19 Library
drwx------ 7 lukas staff 224 12 Feb 2024 Movies
drwx------+ 5 lukas staff 160 25 Sep 2023 Music
drwx------+ 9 lukas staff 288 25 Sep 2023 Pictures
drwx------ 3 lukas staff 96 8 Nov 2021 Postman
drwx------+ 4 lukas staff 128 28 Oct 2021 Public
-rw-r--r--@ 1 lukas staff 3950 15 Dec 09:16 Untitled 4.spf
drwx------ 4 lukas staff 128 2 Jul 2023 Users
drwx------ 3 lukas staff 96 30 Sep 2022 iCloud Drive (Archive)
drwx------ 16 lukas staff 512 3 Nov 11:35 jiminny
drwxr-xr-x 3 lukas staff 96 20 Mar 18:47 node_modules
drwxr-xr-x 4 lukas staff 128 21 Oct 18:15 raycast
-rw-r--r-- 1 lukas staff 0 1 Mar 14:26 response.bin
-rwxr-xr-x 1 lukas staff 3824 11 Apr 15:16 screenpipe-day.sh
-rw-r--r-- 1 lukas staff 86 20 Mar 18:47 yarn.lock
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ nano .zshrc
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ echo "alias sp-status='curl -s [URL_WITH_CREDENTIALS] ~ $ source ~/.zprofile
Poetry could not find a pyproject.toml file in /Users/lukas or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sp-status
{
"status": "healthy",
"frame_status": "ok",
"audio_status": "disabled",
"last_frame": "2026-04-11T18:47:17+03:00",
"uptime": 345.971219541,
"fps": 0.[CREDIT_CARD],
"frames": 34
}
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $
DOCKER
Close Tab
DEV (-zsh)
Close Tab
APP (-zsh)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
ssh
Close Tab
⌥⌘1
-zsh...
|
iTerm2
|
-zsh
|
NULL
|
|
drwx------ 1 lukas staff 16384 11 Apr 16:34 sc drwx------ 1 lukas staff 16384 11 Apr 16:34 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ touch /Volumes/screenpipe/test.txt
touch: /Volumes/screenpipe/test.txt: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ umount /Volumes/screenpipe
umount: unmount(/Volumes/screenpipe): Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ touch /Volumes/screenpipe/test.txt
touch: /Volumes/screenpipe/test.txt: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/db.sqlite
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ scp ~/.screenpipe/db.sqlite Adm1n@[IP_ADDRESS]:/volume1/screenpipe/db.sqlite
scp: dest open "/volume1/screenpipe/db.sqlite": No such file or directory
scp: failed to upload file /Users/lukas/.screenpipe/db.sqlite to /volume1/screenpipe/db.sqlite
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ scp ~/.screenpipe/db.sqlite Adm1n@[IP_ADDRESS]:/volume1/screenpipe/
scp: dest open "/volume1/screenpipe/": No such file or directory
scp: failed to upload file /Users/lukas/.screenpipe/db.sqlite to /volume1/screenpipe/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ll
total 32
drwxr-xr-x 4 root wheel 128 11 Apr 16:35 .
drwxr-xr-x 20 root wheel 640 4 Aug 2024 ..
lrwxr-xr-x 1 root wheel 1 11 Apr 11:13 Macintosh HD -> /
drwx------ 1 lukas staff 16384 11 Apr 16:34 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $clear
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: touch:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: bad pattern: unmount(/Volumes/screenpipe):
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: touch:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: cp:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: scp:
zsh: command not found: scp:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: scp:
zsh: command not found: scp:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: total
zsh: command not found: drwxr-xr-x
zsh: command not found: drwxr-xr-x
zsh: file exists: /
zsh: command not found: drwx------
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ clear
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ scp ~/.screenpipe/db.sqlite Adm1n@[IP_ADDRESS]:/volume1/screenpipe/db.sqlite
scp: dest open "/volume1/screenpipe/db.sqlite": No such file or directory
scp: failed to upload file /Users/lukas/.screenpipe/db.sqlite to /volume1/screenpipe/db.sqlite
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ls
Macintosh HD screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ll
total 32
drwxr-xr-x 4 root wheel 128 11 Apr 16:35 .
drwxr-xr-x 20 root wheel 640 4 Aug 2024 ..
lrwxr-xr-x 1 root wheel 1 11 Apr 11:13 Macintosh HD -> /
drwx------ 1 lukas staff 16384 11 Apr 16:34 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/db.sqlite
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/Test/screenpipe/db.sqlite
cp: /Volumes/Test/screenpipe/db.sqlite: No such file or directory
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/Test/screenpipe/
cp: directory /Volumes/Test/screenpipe does not exist
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/Test/screenpipe/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/db.sqlite
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ll
total 96
drwxr-xr-x 6 root wheel 192 11 Apr 16:45 .
drwxr-xr-x 20 root wheel 640 4 Aug 2024 ..
drwx------ 1 lukas staff 16384 10 Aug 2025 Apps
lrwxr-xr-x 1 root wheel 1 11 Apr 11:13 Macintosh HD -> /
drwx------ 1 lukas staff 16384 11 Apr 15:46 Test
drwx------ 1 lukas staff 16384 11 Apr 16:47 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp -r ~/.screenpipe/pipes/ /Volumes/Test/screenpipe/pipes/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp -r ~/.screenpipe/data/data/ /Volumes/Test/screenpipe/data/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ sed 's|$HOME/.screenpipe/db.sqlite|/volume1/Test/screenpipe/db.sqlite|g' ~/screenpipe-day.sh > /volume1/Test/screenpipe/screenpipe-day.sh
zsh: no such file or directory: /volume1/Test/screenpipe/screenpipe-day.sh
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cat ~/screenpipe-day.sh
#!/bin/zsh
DB="$HOME/.screenpipe/db.sqlite"
DATE=${1:-$(date -v-1d '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo "\n⌨️ ACTIVITY TYPE PER APP (clicks / keys / switches)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo "\n🌐 BROWSER URLS VISITED"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo "\n📋 CLIPBOARD ACTIVITY"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo "\n💬 OCR TEXT SAMPLES PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-15s %s', o.app_name, SUBSTR(o.text, 1, 80))
FROM ocr_text o
JOIN frames f ON o.frame_id = f.id
WHERE date(f.timestamp) = '$DATE' AND o.app_name IS NOT NULL AND o.text != ''
GROUP BY o.app_name
ORDER BY o.app_name LIMIT 15;"
echo "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT
'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';
"
sqlite3 "$DB" "
SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';
"
sqlite3 "$DB" "
SELECT 'OCR texts: ' || COUNT(*) FROM ocr_text o JOIN frames f ON o.frame_id = f.id WHERE date(f.timestamp) = '$DATE';
"
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ curl -X POST [URL_WITH_CREDENTIALS] /Volumes $ curl -X POST [URL_WITH_CREDENTIALS] /Volumes $ curl [URL_WITH_CREDENTIALS] /Volumes $ curl -s [URL_WITH_CREDENTIALS] /Volumes $ echo "alias sp-status='curl -s [URL_WITH_CREDENTIALS] /Volumes $ sp-status
zsh: command not found: sp-status
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ source ~/.zprofile
Poetry could not find a pyproject.toml file in /Volumes or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ sp-status
zsh: command not found: sp-status
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ zp
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ls
Apps Macintosh HD Test screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cd
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ ll
total 1272
drwx------+ 89 lukas staff 2848 11 Apr 18:38 .
drwxr-xr-x 5 root admin 160 23 Aug 2024 ..
-r-------- 1 lukas staff 7 18 Nov 2021 .CFUserTextEncoding
-rw-r--r--@ 1 lukas staff 22532 11 Apr 16:46 .DS_Store
drwx------+ 2 lukas staff 64 11 Apr 11:15 .Trash
drwx------ 5 lukas staff 160 1 Nov 2021 .aws
-rw-r--r-- 1 lukas staff 341470 29 Sep 2022 .babel.json
-rw-------@ 1 lukas staff 388 25 Jul 2025 .bash_history
-rw-r--r--@ 1 lukas staff 77 9 Feb 2023 .bashrc
drwxr-xr-x 5 lukas staff 160 11 Mar 2023 .bito
drwx------@ 6 lukas staff 192 9 Apr 19:53 .cache
drwxr-xr-x 20 lukas staff 640 9 Apr 21:21 .claude
-rw------- 1 lukas staff 24973 9 Apr 21:24 .claude.json
drwxr-xr-x@ 20 lukas staff 640 12 Mar 09:12 .codeium
drwxrwxrwx@ 3 lukas staff 96 2 Mar 2023 .composer
drwx------ 16 lukas staff 512 21 May 2025 .config
drwxr-xr-x 15 lukas staff 480 23 Dec 2024 .continue
drwx------@ 3 lukas staff 96 16 Feb 19:13 .copilot
drwxr-xr-x@ 5 lukas staff 160 9 Apr 2025 .cursor
drwxr-xr-x@ 5 lukas staff 160 17 Aug 2024 .cursor-tutor
drwxr-xr-x 3 lukas staff 96 8 Sep 2024 .daytona
drwxr-xr-x@ 4 lukas staff 128 18 Feb 10:52 .devdb
drwx------ 24 lukas staff 768 9 Apr 18:24 .docker
drwx------ 15 lukas staff 480 6 Jun 2023 .dropbox
drwxr-xr-x@ 3 lukas staff 96 20 Nov 2022 .fig.dotfiles.bak
-rw-r--r-- 1 lukas staff 138 5 Mar 2022 .gauth
-rw-r--r-- 1 lukas staff 220 25 Nov 2021 .gitconfig
-rw-r--r-- 1 lukas staff 12288 25 Nov 2021 .gitconfig.swp
drwx------ 5 lukas staff 160 18 Nov 2021 .hammerspoon
drwxr-xr-x 3 lukas staff 96 21 Mar 2025 .idlerc
-rw------- 1 lukas staff 20 31 Mar 18:32 .lesshst
drwx------ 5 lukas staff 160 23 Dec 2024 .local
-rw------- 1 lukas staff 204 16 Mar 2024 .netrc
drwx------ 3 lukas staff 96 1 Nov 2021 .node-gyp
-rw------- 1 lukas staff 4 6 Feb 2024 .node_repl_history
-rw-r--r-- 1 lukas staff 17 24 Dec 2023 .notion-enhancer
drwxr-xr-x 4 lukas staff 128 12 Jul 2024 .notion-py
drwx------ 9 lukas staff 288 11 Apr 18:41 .npm
-rw------- 1 lukas staff 74 20 May 2024 .npmrc
drwx------ 32 lukas staff 1024 25 Jul 2025 .nvm
drwxr-xr-x 4 lukas staff 128 5 Aug 2023 .postman
-rw-r--r--@ 1 lukas staff 77 9 Feb 2023 .profile
-rw-------@ 1 lukas staff 3153 21 Mar 2025 .python_history
drwx------ 2 lukas staff 64 15 Nov 2021 .quicktype-vscode
drwxr-xr-x@ 8 lukas staff 256 16 Feb 08:48 .redis-insight
drwxr-xr-x 10 lukas staff 320 11 Apr 14:52 .screenpipe
UW PICO 5.09 New Buffer
[ Read 11 lines ]
^G Get Help ^O WriteOut ^R Read File ^Y Prev Pg ^K Cut Text ^C Cur Pos
^X Exit ^J Justify ^W Where is ^V Next Pg ^U UnCut Text ^T To Spell
drwxr-xr-x 4 lukas staff 128 4 Feb 09:35 .sonarlint
drwx------ 15 lukas staff 480 8 Aug 2025 .ssh
drwxr-xr-x@ 3 lukas staff 96 15 Aug 2025 .streamlit
drwx------ 6 lukas staff 192 17 Oct 2022 .swiftpm
-rw------- 1 lukas staff 12183 8 Apr 19:14 .viminfo
drwx------ 5 lukas staff 160 19 Jun 2023 .vscode
drwxr-xr-x@ 3 lukas staff 96 20 Jan 2025 .warp
drwxr-xr-x 4 lukas staff 128 29 Apr 2023 .wdm
drwxr-xr-x@ 5 lukas staff 160 26 Jan 13:03 .windsurf
drwxr-xr-x 4 lukas staff 128 24 Mar 12:03 .yarn
-rw-r--r-- 1 lukas staff 116 30 Mar 10:12 .yarnrc
-rw-r--r--@ 1 lukas staff 49518 6 Apr 14:31 .zcompdump
-rw-r--r--@ 1 lukas staff 46758 2 Nov 20:34 .zcompdump.Lukas-Kovaliks-MacBook-Pro-Jiminny.23381
-rw-r--r--@ 1 lukas staff 5641 9 Apr 20:30 .zprofile
-rw-r--r-- 1 lukas staff 1468 8 Apr 2022 .zprofile-copy
-rw-r--r--@ 1 lukas staff 2900 15 Mar 2023 .zprofile.pysave
-rw------- 1 lukas staff 1731 29 Jun 2022 .zprofile.save
-rw-r--r-- 1 lukas staff 1569 8 Apr 2022 .zprofilees
UW PICO 5.09 New Buffer
[ Read 13 lines ]
^G Get Help ^O WriteOut ^R Read File ^Y Prev Pg ^K Cut Text ^C Cur Pos
^X Exit ^J Justify ^W Where is ^V Next Pg ^U UnCut Text ^T To Spell
-rw------- 1 lukas staff 28812 11 Apr 18:38 .zsh_history
drwx------ 9 lukas staff 288 6 May 2025 .zsh_sessions
-rw-r--r--@ 1 lukas staff 597 11 Apr 18:44 .zshrc
drwx------@ 9 lukas staff 288 9 Apr 20:08 Applications
drwxr-xr-x@ 2 lukas staff 64 22 Oct 09:35 CascadeProjects
drwxr-xr-x 4 lukas staff 128 27 Oct 09:24 DEV
drwx------@ 10 lukas staff 320 11 Apr 18:31 Desktop
drwx------@ 7 lukas staff 224 26 Mar 14:40 Documents
drwx------@ 41 lukas staff 1312 8 Apr 20:46 Downloads
drwxr-xr-x@ 4 lukas staff 128 17 Mar 20:27 Keychron_Screen
drwx------@ 112 lukas staff 3584 2 Dec 09:19 Library
drwx------ 7 lukas staff 224 12 Feb 2024 Movies
drwx------+ 5 lukas staff 160 25 Sep 2023 Music
drwx------+ 9 lukas staff 288 25 Sep 2023 Pictures
drwx------ 3 lukas staff 96 8 Nov 2021 Postman
drwx------+ 4 lukas staff 128 28 Oct 2021 Public
-rw-r--r--@ 1 lukas staff 3950 15 Dec 09:16 Untitled 4.spf
drwx------ 4 lukas staff 128 2 Jul 2023 Users
drwx------ 3 lukas staff 96 30 Sep 2022 iCloud Drive (Archive)
drwx------ 16 lukas staff 512 3 Nov 11:35 jiminny
drwxr-xr-x 3 lukas staff 96 20 Mar 18:47 node_modules
drwxr-xr-x 4 lukas staff 128 21 Oct 18:15 raycast
-rw-r--r-- 1 lukas staff 0 1 Mar 14:26 response.bin
-rwxr-xr-x 1 lukas staff 3824 11 Apr 15:16 screenpipe-day.sh
-rw-r--r-- 1 lukas staff 86 20 Mar 18:47 yarn.lock
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ nano .zshrc
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ echo "alias sp-status='curl -s [URL_WITH_CREDENTIALS] ~ $ source ~/.zprofile
Poetry could not find a pyproject.toml file in /Users/lukas or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sp-status
{
"status": "healthy",
"frame_status": "ok",
"audio_status": "disabled",
"last_frame": "2026-04-11T18:47:17+03:00",
"uptime": 345.971219541,
"fps": 0.[CREDIT_CARD],
"frames": 34
}
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sp-stop
screenpipe stopped
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ nano ~/.screenpipe/config.json
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sp-start
[1] 41216
detected hardware tier: Mid
checking permissions...
screen recording: ok
accessibility: ok
2026-04-11T18:54:13.170097Z INFO screenpipe_screen::monitor::macos_version: Detected macOS version: 14.6
2026-04-11T18:54:13.812964Z INFO screenpipe_engine::sleep_monitor: Starting macOS sleep/wake monitor
2026-04-11T18:54:13.819889Z INFO screenpipe: meeting detector enabled — independent of transcription mode
2026-04-11T18:54:13.819889Z INFO screenpipe_engine::sleep_monitor: Screen lock/unlock observers registered (CFNotificationCenter)
2026-04-11T18:54:13.820291Z INFO screenpipe_engine::snapshot_compaction: snapshot compaction worker started (min_age=600s, poll=300s)
2026-04-11T18:54:13.820220Z INFO screenpipe_engine::power::manager: power manager started (poll interval: 10s)
2026-04-11T18:54:13.820450Z INFO screenpipe_engine::vision_manager::manager: Starting VisionManager
2026-04-11T18:54:13.820896Z INFO screenpipe_core::pipes: loaded pipe: day-recap
2026-04-11T18:54:13.820856Z INFO screenpipe_engine::sleep_monitor: Display reconfiguration watcher registered (CGDisplayRegisterReconfigurationCallback)
2026-04-11T18:54:13.821123Z INFO screenpipe_core::pipes: loaded pipe: standup-update
2026-04-11T18:54:13.821801Z INFO screenpipe_core::pipes: loaded pipe: ai-habits
2026-04-11T18:54:13.821972Z INFO screenpipe_core::pipes: loaded pipe: time-breakdown
2026-04-11T18:54:13.822128Z INFO screenpipe_core::pipes: loaded pipe: video-export
2026-04-11T18:54:13.822942Z INFO screenpipe_core::pipes: loaded pipe: meeting-summary
2026-04-11T18:54:13.822962Z INFO screenpipe_core::pipes: loaded 6 pipes from "/Users/lukas/.screenpipe/pipes"
_
__________________ ___ ____ ____ (_____ ___
/ ___/ ___/ ___/ _ \/ _ \/ __ \ / __ \/ / __ \/ _ \
(__ / /__/ / / __/ __/ / / / / /_/ / / /_/ / __/
/____/\___/_/ \___/\___/_/ /_/ / .___/_/ .___/\___/
/_/ /_/
power AI by everything you've seen, said or heard
open source | runs locally | developer friendly
┌────────────────────────┬────────────────────────────────────┐
│ setting │ value │
├────────────────────────┼────────────────────────────────────┤
│ audio chunk duration │ 30 seconds │
│ port │ 3030 │
│ audio disabled │ true │
│ vision disabled │ false │
│ pause on DRM content │ false │
│ audio engine │ Parakeet │
│ vad engine │ Silero │
│ data directory │ /Users/lukas/.screenpipe │
│ debug mode │ false │
│ telemetry │ true │
│ use pii removal │ true │
│ use all monitors │ true │
│ ignored windows │ [] │
│ included windows │ [] │
│ cloud sync │ disabled │
│ auto-destruct pid │ 0 │
│ deepgram key │ not set │
├────────────────────────┼────────────────────────────────────┤
│ languages │ │
│ │ all languages │
├────────────────────────┼────────────────────────────────────┤
│ monitors │ │
│ │ no monitors available │
├────────────────────────┼────────────────────────────────────┤
│ audio devices │ │
│ │ disabled │
└────────────────────────┴────────────────────────────────────┘
you are using local processing. all your data stays on your computer.
warning: telemetry is enabled. only error-level data will be sent.
to disable, use the --disable-telemetry flag.
check latest changes here: https://github.com/screenpipe/screenpipe/releases
2026-04-11T18:54:13.824479Z INFO screenpipe_core::pipes: pipe scheduler started (generation 2)
2026-04-11T18:54:13.824829Z INFO screenpipe: starting UI event capture
2026-04-11T18:54:13.828568Z WARN screenpipe: pi agent install failed: bun not found — install from https://bun.sh
2026-04-11T18:54:13.829646Z INFO screenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))
2026-04-11T18:54:13.838998Z INFO screenpipe_engine::ui_recorder: Starting UI event capture
2026-04-11T18:54:13.852999Z INFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)
2026-04-11T18:54:13.853108Z INFO screenpipe_engine::hot_frame_cache: hot_frame_cache: warming from DB (2026-04-10 15:54:13.853107 UTC to 2026-04-11 15:54:13.853107 UTC)
2026-04-11T18:54:13.853121Z INFO screenpipe_engine::ui_recorder: UI recording session started: 13f9ef4b-a7db-47ce-844f-778b4b926db5
2026-04-11T18:54:13.854048Z INFO screenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)
2026-04-11T18:54:13.859344Z INFO screenpipe_engine::server: Server listening on [IP_ADDRESS]:3030
2026-04-11T18:54:13.864448Z INFO screenpipe_connect::mdns: mdns: advertising screenpipe on port 3030
2026-04-11T18:54:14.006638Z INFO screenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 878 frame entries, coverage from 2026-04-10 15:54:13.853107 UTC
2026-04-11T18:54:14.161101Z INFO screenpipe_engine::vision_manager::manager: Starting vision recording for monitor 1 (1440x900)
2026-04-11T18:54:14.161134Z INFO screenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)
2026-04-11T18:54:14.161145Z INFO screenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) — not in allowed list
2026-04-11T18:54:14.161153Z INFO screenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)
2026-04-11T18:54:14.161204Z INFO screenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)
2026-04-11T18:54:14.958802Z INFO sck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)
DOCKER
Close Tab
DEV (-zsh)
Close Tab
APP (-zsh)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
ssh
Close Tab
⌥⌘1
-zsh...
|
iTerm2
|
-zsh
|
NULL
|
|
drwx------ 1 lukas staff 16384 11 Apr 16:34 sc drwx------ 1 lukas staff 16384 11 Apr 16:34 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ touch /Volumes/screenpipe/test.txt
touch: /Volumes/screenpipe/test.txt: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ umount /Volumes/screenpipe
umount: unmount(/Volumes/screenpipe): Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ touch /Volumes/screenpipe/test.txt
touch: /Volumes/screenpipe/test.txt: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/db.sqlite
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ scp ~/.screenpipe/db.sqlite Adm1n@[IP_ADDRESS]:/volume1/screenpipe/db.sqlite
scp: dest open "/volume1/screenpipe/db.sqlite": No such file or directory
scp: failed to upload file /Users/lukas/.screenpipe/db.sqlite to /volume1/screenpipe/db.sqlite
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ scp ~/.screenpipe/db.sqlite Adm1n@[IP_ADDRESS]:/volume1/screenpipe/
scp: dest open "/volume1/screenpipe/": No such file or directory
scp: failed to upload file /Users/lukas/.screenpipe/db.sqlite to /volume1/screenpipe/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ll
total 32
drwxr-xr-x 4 root wheel 128 11 Apr 16:35 .
drwxr-xr-x 20 root wheel 640 4 Aug 2024 ..
lrwxr-xr-x 1 root wheel 1 11 Apr 11:13 Macintosh HD -> /
drwx------ 1 lukas staff 16384 11 Apr 16:34 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $clear
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: touch:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: bad pattern: unmount(/Volumes/screenpipe):
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: touch:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: cp:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: scp:
zsh: command not found: scp:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: scp:
zsh: command not found: scp:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: total
zsh: command not found: drwxr-xr-x
zsh: command not found: drwxr-xr-x
zsh: file exists: /
zsh: command not found: drwx------
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ clear
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ scp ~/.screenpipe/db.sqlite Adm1n@[IP_ADDRESS]:/volume1/screenpipe/db.sqlite
scp: dest open "/volume1/screenpipe/db.sqlite": No such file or directory
scp: failed to upload file /Users/lukas/.screenpipe/db.sqlite to /volume1/screenpipe/db.sqlite
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ls
Macintosh HD screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ll
total 32
drwxr-xr-x 4 root wheel 128 11 Apr 16:35 .
drwxr-xr-x 20 root wheel 640 4 Aug 2024 ..
lrwxr-xr-x 1 root wheel 1 11 Apr 11:13 Macintosh HD -> /
drwx------ 1 lukas staff 16384 11 Apr 16:34 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/db.sqlite
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/Test/screenpipe/db.sqlite
cp: /Volumes/Test/screenpipe/db.sqlite: No such file or directory
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/Test/screenpipe/
cp: directory /Volumes/Test/screenpipe does not exist
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/Test/screenpipe/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/db.sqlite
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ll
total 96
drwxr-xr-x 6 root wheel 192 11 Apr 16:45 .
drwxr-xr-x 20 root wheel 640 4 Aug 2024 ..
drwx------ 1 lukas staff 16384 10 Aug 2025 Apps
lrwxr-xr-x 1 root wheel 1 11 Apr 11:13 Macintosh HD -> /
drwx------ 1 lukas staff 16384 11 Apr 15:46 Test
drwx------ 1 lukas staff 16384 11 Apr 16:47 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp -r ~/.screenpipe/pipes/ /Volumes/Test/screenpipe/pipes/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp -r ~/.screenpipe/data/data/ /Volumes/Test/screenpipe/data/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ sed 's|$HOME/.screenpipe/db.sqlite|/volume1/Test/screenpipe/db.sqlite|g' ~/screenpipe-day.sh > /volume1/Test/screenpipe/screenpipe-day.sh
zsh: no such file or directory: /volume1/Test/screenpipe/screenpipe-day.sh
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cat ~/screenpipe-day.sh
#!/bin/zsh
DB="$HOME/.screenpipe/db.sqlite"
DATE=${1:-$(date -v-1d '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo "\n⌨️ ACTIVITY TYPE PER APP (clicks / keys / switches)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo "\n🌐 BROWSER URLS VISITED"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo "\n📋 CLIPBOARD ACTIVITY"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo "\n💬 OCR TEXT SAMPLES PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-15s %s', o.app_name, SUBSTR(o.text, 1, 80))
FROM ocr_text o
JOIN frames f ON o.frame_id = f.id
WHERE date(f.timestamp) = '$DATE' AND o.app_name IS NOT NULL AND o.text != ''
GROUP BY o.app_name
ORDER BY o.app_name LIMIT 15;"
echo "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT
'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';
"
sqlite3 "$DB" "
SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';
"
sqlite3 "$DB" "
SELECT 'OCR texts: ' || COUNT(*) FROM ocr_text o JOIN frames f ON o.frame_id = f.id WHERE date(f.timestamp) = '$DATE';
"
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ curl -X POST [URL_WITH_CREDENTIALS] /Volumes $ curl -X POST [URL_WITH_CREDENTIALS] /Volumes $ curl [URL_WITH_CREDENTIALS] /Volumes $ curl -s [URL_WITH_CREDENTIALS] /Volumes $ echo "alias sp-status='curl -s [URL_WITH_CREDENTIALS] /Volumes $ sp-status
zsh: command not found: sp-status
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ source ~/.zprofile
Poetry could not find a pyproject.toml file in /Volumes or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ sp-status
zsh: command not found: sp-status
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ zp
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ls
Apps Macintosh HD Test screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cd
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ ll
total 1272
drwx------+ 89 lukas staff 2848 11 Apr 18:38 .
drwxr-xr-x 5 root admin 160 23 Aug 2024 ..
-r-------- 1 lukas staff 7 18 Nov 2021 .CFUserTextEncoding
-rw-r--r--@ 1 lukas staff 22532 11 Apr 16:46 .DS_Store
drwx------+ 2 lukas staff 64 11 Apr 11:15 .Trash
drwx------ 5 lukas staff 160 1 Nov 2021 .aws
-rw-r--r-- 1 lukas staff 341470 29 Sep 2022 .babel.json
-rw-------@ 1 lukas staff 388 25 Jul 2025 .bash_history
-rw-r--r--@ 1 lukas staff 77 9 Feb 2023 .bashrc
drwxr-xr-x 5 lukas staff 160 11 Mar 2023 .bito
drwx------@ 6 lukas staff 192 9 Apr 19:53 .cache
drwxr-xr-x 20 lukas staff 640 9 Apr 21:21 .claude
-rw------- 1 lukas staff 24973 9 Apr 21:24 .claude.json
drwxr-xr-x@ 20 lukas staff 640 12 Mar 09:12 .codeium
drwxrwxrwx@ 3 lukas staff 96 2 Mar 2023 .composer
drwx------ 16 lukas staff 512 21 May 2025 .config
drwxr-xr-x 15 lukas staff 480 23 Dec 2024 .continue
drwx------@ 3 lukas staff 96 16 Feb 19:13 .copilot
drwxr-xr-x@ 5 lukas staff 160 9 Apr 2025 .cursor
drwxr-xr-x@ 5 lukas staff 160 17 Aug 2024 .cursor-tutor
drwxr-xr-x 3 lukas staff 96 8 Sep 2024 .daytona
drwxr-xr-x@ 4 lukas staff 128 18 Feb 10:52 .devdb
drwx------ 24 lukas staff 768 9 Apr 18:24 .docker
drwx------ 15 lukas staff 480 6 Jun 2023 .dropbox
drwxr-xr-x@ 3 lukas staff 96 20 Nov 2022 .fig.dotfiles.bak
-rw-r--r-- 1 lukas staff 138 5 Mar 2022 .gauth
-rw-r--r-- 1 lukas staff 220 25 Nov 2021 .gitconfig
-rw-r--r-- 1 lukas staff 12288 25 Nov 2021 .gitconfig.swp
drwx------ 5 lukas staff 160 18 Nov 2021 .hammerspoon
drwxr-xr-x 3 lukas staff 96 21 Mar 2025 .idlerc
-rw------- 1 lukas staff 20 31 Mar 18:32 .lesshst
drwx------ 5 lukas staff 160 23 Dec 2024 .local
-rw------- 1 lukas staff 204 16 Mar 2024 .netrc
drwx------ 3 lukas staff 96 1 Nov 2021 .node-gyp
-rw------- 1 lukas staff 4 6 Feb 2024 .node_repl_history
-rw-r--r-- 1 lukas staff 17 24 Dec 2023 .notion-enhancer
drwxr-xr-x 4 lukas staff 128 12 Jul 2024 .notion-py
drwx------ 9 lukas staff 288 11 Apr 18:41 .npm
-rw------- 1 lukas staff 74 20 May 2024 .npmrc
drwx------ 32 lukas staff 1024 25 Jul 2025 .nvm
drwxr-xr-x 4 lukas staff 128 5 Aug 2023 .postman
-rw-r--r--@ 1 lukas staff 77 9 Feb 2023 .profile
-rw-------@ 1 lukas staff 3153 21 Mar 2025 .python_history
drwx------ 2 lukas staff 64 15 Nov 2021 .quicktype-vscode
drwxr-xr-x@ 8 lukas staff 256 16 Feb 08:48 .redis-insight
drwxr-xr-x 10 lukas staff 320 11 Apr 14:52 .screenpipe
UW PICO 5.09 New Buffer
[ Read 11 lines ]
^G Get Help ^O WriteOut ^R Read File ^Y Prev Pg ^K Cut Text ^C Cur Pos
^X Exit ^J Justify ^W Where is ^V Next Pg ^U UnCut Text ^T To Spell
drwxr-xr-x 4 lukas staff 128 4 Feb 09:35 .sonarlint
drwx------ 15 lukas staff 480 8 Aug 2025 .ssh
drwxr-xr-x@ 3 lukas staff 96 15 Aug 2025 .streamlit
drwx------ 6 lukas staff 192 17 Oct 2022 .swiftpm
-rw------- 1 lukas staff 12183 8 Apr 19:14 .viminfo
drwx------ 5 lukas staff 160 19 Jun 2023 .vscode
drwxr-xr-x@ 3 lukas staff 96 20 Jan 2025 .warp
drwxr-xr-x 4 lukas staff 128 29 Apr 2023 .wdm
drwxr-xr-x@ 5 lukas staff 160 26 Jan 13:03 .windsurf
drwxr-xr-x 4 lukas staff 128 24 Mar 12:03 .yarn
-rw-r--r-- 1 lukas staff 116 30 Mar 10:12 .yarnrc
-rw-r--r--@ 1 lukas staff 49518 6 Apr 14:31 .zcompdump
-rw-r--r--@ 1 lukas staff 46758 2 Nov 20:34 .zcompdump.Lukas-Kovaliks-MacBook-Pro-Jiminny.23381
-rw-r--r--@ 1 lukas staff 5641 9 Apr 20:30 .zprofile
-rw-r--r-- 1 lukas staff 1468 8 Apr 2022 .zprofile-copy
-rw-r--r--@ 1 lukas staff 2900 15 Mar 2023 .zprofile.pysave
-rw------- 1 lukas staff 1731 29 Jun 2022 .zprofile.save
-rw-r--r-- 1 lukas staff 1569 8 Apr 2022 .zprofilees
UW PICO 5.09 New Buffer
[ Read 13 lines ]
^G Get Help ^O WriteOut ^R Read File ^Y Prev Pg ^K Cut Text ^C Cur Pos
^X Exit ^J Justify ^W Where is ^V Next Pg ^U UnCut Text ^T To Spell
-rw------- 1 lukas staff 28812 11 Apr 18:38 .zsh_history
drwx------ 9 lukas staff 288 6 May 2025 .zsh_sessions
-rw-r--r--@ 1 lukas staff 597 11 Apr 18:44 .zshrc
drwx------@ 9 lukas staff 288 9 Apr 20:08 Applications
drwxr-xr-x@ 2 lukas staff 64 22 Oct 09:35 CascadeProjects
drwxr-xr-x 4 lukas staff 128 27 Oct 09:24 DEV
drwx------@ 10 lukas staff 320 11 Apr 18:31 Desktop
drwx------@ 7 lukas staff 224 26 Mar 14:40 Documents
drwx------@ 41 lukas staff 1312 8 Apr 20:46 Downloads
drwxr-xr-x@ 4 lukas staff 128 17 Mar 20:27 Keychron_Screen
drwx------@ 112 lukas staff 3584 2 Dec 09:19 Library
drwx------ 7 lukas staff 224 12 Feb 2024 Movies
drwx------+ 5 lukas staff 160 25 Sep 2023 Music
drwx------+ 9 lukas staff 288 25 Sep 2023 Pictures
drwx------ 3 lukas staff 96 8 Nov 2021 Postman
drwx------+ 4 lukas staff 128 28 Oct 2021 Public
-rw-r--r--@ 1 lukas staff 3950 15 Dec 09:16 Untitled 4.spf
drwx------ 4 lukas staff 128 2 Jul 2023 Users
drwx------ 3 lukas staff 96 30 Sep 2022 iCloud Drive (Archive)
drwx------ 16 lukas staff 512 3 Nov 11:35 jiminny
drwxr-xr-x 3 lukas staff 96 20 Mar 18:47 node_modules
drwxr-xr-x 4 lukas staff 128 21 Oct 18:15 raycast
-rw-r--r-- 1 lukas staff 0 1 Mar 14:26 response.bin
-rwxr-xr-x 1 lukas staff 3824 11 Apr 15:16 screenpipe-day.sh
-rw-r--r-- 1 lukas staff 86 20 Mar 18:47 yarn.lock
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ nano .zshrc
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ echo "alias sp-status='curl -s [URL_WITH_CREDENTIALS] ~ $ source ~/.zprofile
Poetry could not find a pyproject.toml file in /Users/lukas or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sp-status
{
"status": "healthy",
"frame_status": "ok",
"audio_status": "disabled",
"last_frame": "2026-04-11T18:47:17+03:00",
"uptime": 345.971219541,
"fps": 0.[CREDIT_CARD],
"frames": 34
}
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sp-stop
screenpipe stopped
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ nano ~/.screenpipe/config.json
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sp-start
[1] 41216
detected hardware tier: Mid
checking permissions...
screen recording: ok
accessibility: ok
2026-04-11T18:54:13.170097Z INFO screenpipe_screen::monitor::macos_version: Detected macOS version: 14.6
2026-04-11T18:54:13.812964Z INFO screenpipe_engine::sleep_monitor: Starting macOS sleep/wake monitor
2026-04-11T18:54:13.819889Z INFO screenpipe: meeting detector enabled — independent of transcription mode
2026-04-11T18:54:13.819889Z INFO screenpipe_engine::sleep_monitor: Screen lock/unlock observers registered (CFNotificationCenter)
2026-04-11T18:54:13.820291Z INFO screenpipe_engine::snapshot_compaction: snapshot compaction worker started (min_age=600s, poll=300s)
2026-04-11T18:54:13.820220Z INFO screenpipe_engine::power::manager: power manager started (poll interval: 10s)
2026-04-11T18:54:13.820450Z INFO screenpipe_engine::vision_manager::manager: Starting VisionManager
2026-04-11T18:54:13.820896Z INFO screenpipe_core::pipes: loaded pipe: day-recap
2026-04-11T18:54:13.820856Z INFO screenpipe_engine::sleep_monitor: Display reconfiguration watcher registered (CGDisplayRegisterReconfigurationCallback)
2026-04-11T18:54:13.821123Z INFO screenpipe_core::pipes: loaded pipe: standup-update
2026-04-11T18:54:13.821801Z INFO screenpipe_core::pipes: loaded pipe: ai-habits
2026-04-11T18:54:13.821972Z INFO screenpipe_core::pipes: loaded pipe: time-breakdown
2026-04-11T18:54:13.822128Z INFO screenpipe_core::pipes: loaded pipe: video-export
2026-04-11T18:54:13.822942Z INFO screenpipe_core::pipes: loaded pipe: meeting-summary
2026-04-11T18:54:13.822962Z INFO screenpipe_core::pipes: loaded 6 pipes from "/Users/lukas/.screenpipe/pipes"
_
__________________ ___ ____ ____ (_____ ___
/ ___/ ___/ ___/ _ \/ _ \/ __ \ / __ \/ / __ \/ _ \
(__ / /__/ / / __/ __/ / / / / /_/ / / /_/ / __/
/____/\___/_/ \___/\___/_/ /_/ / .___/_/ .___/\___/
/_/ /_/
power AI by everything you've seen, said or heard
open source | runs locally | developer friendly
┌────────────────────────┬────────────────────────────────────┐
│ setting │ value │
├────────────────────────┼────────────────────────────────────┤
│ audio chunk duration │ 30 seconds │
│ port │ 3030 │
│ audio disabled │ true │
│ vision disabled │ false │
│ pause on DRM content │ false │
│ audio engine │ Parakeet │
│ vad engine │ Silero │
│ data directory │ /Users/lukas/.screenpipe │
│ debug mode │ false │
│ telemetry │ true │
│ use pii removal │ true │
│ use all monitors │ true │
│ ignored windows │ [] │
│ included windows │ [] │
│ cloud sync │ disabled │
│ auto-destruct pid │ 0 │
│ deepgram key │ not set │
├────────────────────────┼────────────────────────────────────┤
│ languages │ │
│ │ all languages │
├────────────────────────┼────────────────────────────────────┤
│ monitors │ │
│ │ no monitors available │
├────────────────────────┼────────────────────────────────────┤
│ audio devices │ │
│ │ disabled │
└────────────────────────┴────────────────────────────────────┘
you are using local processing. all your data stays on your computer.
warning: telemetry is enabled. only error-level data will be sent.
to disable, use the --disable-telemetry flag.
check latest changes here: [URL_WITH_CREDENTIALS] ~ $ 2026-04-11T18:54:18.859011Z INFO screenpipe_engine::retention: retention: initialized with 14d retention
2026-04-11T18:54:18.859467Z INFO screenpipe: local retention auto-enabled (14 days)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sp-stop
screenpipe stopped
[1] + terminated npx screenpipe@latest record --disable-audio
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sqlite3 ~/.screenpipe/db.sqlite "
SELECT DISTINCT window_name
FROM frames
WHERE app_name IN ('Safari', 'Firefox', 'Arc', 'Chrome')
AND window_name IS NOT NULL
UW PICO 5.09 New Buffer
[ Read 13 lines ]
^G Get Help ^O WriteOut ^R Read File ^Y Prev Pg ^K Cut Text ^C Cur Pos
^X Exit ^J Justify ^W Where is ^V Next Pg ^U UnCut Text ^T To Spell
ORDER BY window_name;"
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8 — Personal
Denník N - Nezávislý denník — Personal
Edit profile — Personal
Location Logger
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N — Personal
Maďarské voľby – Denník N — Personal
Personal — Mozilla Firefox
Picture-in-Picture
Problem loading page — Personal
Screenpipe Dashboard — Personal
Settings — Personal
Sign in – Google accounts — Personal
Tailscale — Personal
UGREEN NAS — Personal
Vimium Options — Personal
Vimium – Get this Extension for 🦊 Firefox (en-US) — Personal
firefox sidebar - Google Search — Personal
tilscale admin panel - Google Search — Personal
Order Room Service • HBO Max
Shameless • HBO Max
Shameless • HBO Max — Personal
Simple Pleasures • HBO Max — Personal
Časť 2 • HBO Max — Personal
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ cat ~/.screenpipe/config.json
{
"disable_audio": true,
"monitor_ids": ["Display 1_1440x900_0,0", "Display 2_3008x1253_-813,-1253"],
"ignored_windows": [
"1Password",
"Keychain Access",
"Bitwarden",
"System Preferences",
"System Settings",
"zoom.us",
"HBO Max",
]
}
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ nano ~/.screenpipe/config.json
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ pkill screenpipe && sleep 2 && npx screenpipe@latest record
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ pkill screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ npx screenpipe@latest record
detected hardware tier: Mid
checking permissions...
screen recording: ok
microphone: ok
accessibility: ok
2026-04-11T19:00:06.546722Z INFO screenpipe_screen::monitor::macos_version: Detected macOS version: 14.6
2026-04-11T19:00:07.267955Z INFO screenpipe_engine::sleep_monitor: Starting macOS sleep/wake monitor
2026-04-11T19:00:07.269566Z INFO screenpipe: meeting detector enabled — independent of transcription mode
2026-04-11T19:00:07.269564Z INFO screenpipe_engine::sleep_monitor: Screen lock/unlock observers registered (CFNotificationCenter)
2026-04-11T19:00:07.269921Z INFO screenpipe_engine::sleep_monitor: Display reconfiguration watcher registered (CGDisplayRegisterReconfigurationCallback)
2026-04-11T19:00:07.470439Z INFO screenpipe_engine::snapshot_compaction: snapshot compaction worker started (min_age=600s, poll=300s)
2026-04-11T19:00:07.470481Z INFO screenpipe_engine::vision_manager::manager: Starting VisionManager
2026-04-11T19:00:07.470420Z INFO screenpipe_engine::power::manager: power manager started (poll interval: 10s)
2026-04-11T19:00:07.470877Z INFO screenpipe_core::pipes: loaded pipe: day-recap
2026-04-11T19:00:07.471071Z INFO screenpipe_core::pipes: loaded pipe: standup-update
2026-04-11T19:00:07.471748Z INFO screenpipe_core::pipes: loaded pipe: ai-habits
2026-04-11T19:00:07.471948Z INFO screenpipe_core::pipes: loaded pipe: time-breakdown
2026-04-11T19:00:07.472085Z INFO screenpipe_core::pipes: loaded pipe: video-export
2026-04-11T19:00:07.472295Z INFO screenpipe_core::pipes: loaded pipe: meeting-summary
2026-04-11T19:00:07.472315Z INFO screenpipe_core::pipes: loaded 6 pipes from "/Users/lukas/.screenpipe/pipes"
_
__________________ ___ ____ ____ (_____ ___
/ ___/ ___/ ___/ _ \/ _ \/ __ \ / __ \/ / __ \/ _ \
(__ / /__/ / / __/ __/ / / / / /_/ / / /_/ / __/
/____/\___/_/ \___/\___/_/ /_/ / .___/_/ .___/\___/
/_/ /_/
power AI by everything you've seen, said or heard
open source | runs locally | developer friendly
┌────────────────────────┬────────────────────────────────────┐
│ setting │ value │
├────────────────────────┼────────────────────────────────────┤
│ audio chunk duration │ 30 seconds │
│ port │ 3030 │
│ audio disabled │ false │
│ vision disabled │ false │
│ pause on DRM content │ false │
│ audio engine │ Parakeet │
│ vad engine │ Silero │
│ data directory │ /Users/lukas/.screenpipe │
│ debug mode │ false │
│ telemetry │ true │
│ use pii removal │ true │
│ use all monitors │ true │
│ ignored windows │ [] │
│ included windows │ [] │
│ cloud sync │ disabled │
│ auto-destruct pid │ 0 │
│ deepgram key │ not set │
├────────────────────────┼────────────────────────────────────┤
│ languages │ │
│ │ all languages │
├────────────────────────┼────────────────────────────────────┤
│ monitors │ │
│ │ no monitors available │
├────────────────────────┼────────────────────────────────────┤
│ audio devices │ │
│ │ soundcore AeroClip (input) │
│ │ System Audio (output) │
└────────────────────────┴────────────────────────────────────┘
you are using local processing. all your data stays on your computer.
warning: telemetry is enabled. only error-level data will be sent.
to disable, use the --disable-telemetry flag.
check latest changes here: https://github.com/screenpipe/screenpipe/releases
2026-04-11T19:00:07.473167Z INFO screenpipe_core::pipes: pipe scheduler started (generation 2)
2026-04-11T19:00:07.473787Z INFO screenpipe: starting UI event capture
2026-04-11T19:00:07.476515Z WARN screenpipe: pi agent install failed: bun not found — install from https://bun.sh
2026-04-11T19:00:07.485630Z INFO screenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))
2026-04-11T19:00:07.489867Z INFO screenpipe_engine::ui_recorder: Starting UI event capture
2026-04-11T19:00:07.503670Z INFO screenpipe_engine::ui_recorder: UI recording session started: 6b15bcb7-6588-4b6b-9ae5-5a3b50fba2a2
2026-04-11T19:00:07.503881Z INFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)
2026-04-11T19:00:07.503967Z INFO screenpipe_engine::hot_frame_cache: hot_frame_cache: warming from DB (2026-04-10 16:00:07.503966 UTC to 2026-04-11 16:00:07.503966 UTC)
2026-04-11T19:00:07.504283Z INFO screenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)
2026-04-11T19:00:07.509408Z INFO screenpipe_engine::server: Server listening on [IP_ADDRESS]:3030
2026-04-11T19:00:07.514386Z INFO screenpipe_connect::mdns: mdns: advertising screenpipe on port 3030
2026-04-11T19:00:07.659978Z INFO screenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 879 frame entries, coverage from 2026-04-10 16:00:07.503966 UTC
2026-04-11T19:00:07.820721Z INFO screenpipe_engine::vision_manager::manager: Starting vision recording for monitor 1 (1440x900)
2026-04-11T19:00:07.820747Z INFO screenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)
2026-04-11T19:00:07.820758Z INFO screenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) — not in allowed list
2026-04-11T19:00:07.820766Z INFO screenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)
2026-04-11T19:00:07.820805Z INFO screenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)
2026-04-11T19:00:08.565404Z INFO sck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)
DOCKER
Close Tab
DEV (-zsh)
Close Tab
APP (-zsh)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
screenpipe"
Close Tab
-zsh
Close Tab
ssh
Close Tab
⌥⌘1
screenpipe"...
|
iTerm2
|
screenpipe"
|
NULL
|
|
Close
Send back to tab
Backward
Pause
Forward
Mute Close
Send back to tab
Backward
Pause
Forward
Mute
iTerm2• 0DOCKERdata directorydebug modetelemetryuse pii removaluse all monitorsignored windowsincluded windowscloud syncauto-destruct piddeepgram keylanguagesmonitorsaudio devicesShellEditViewSessionScriptsProfilesWindowHelp981DEV (-zsh)282/Users/lukas/.screenpipefalsetruetruetruedisablednot setall languagesAPP (-zsh)83-zshscreenpipe"84-zsh$0(ahlscreenpipe"886-zsh100% <7O 87Sat 11 Apr 19:00:33sshT81*8no monitors availablesoundcore AeroClip (input)System Audio (output)you are using local processing. all your data stays on your computer.warning: telemetry isenabled. onlyerror-levelto disable,usethe--disable-telemetry flag.data will be sent.checklatestchangeshere:https://github.com/screenpipe/screenpipe/releases2026-04-11T19:00:32.667186ZINFOscreenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T19:00:32.667286ZINFOscreenpipe:starting UIevent capture2026-04-11T19:00:32.670076ZWARNscreenpipe:piagentinstall failed: bun not found - install from https://bun.sh2026-04-11719:00:32.6729892INFOscreenpipe_engine::power::manager:initial power profile: Performance2026-04-11T19:00:32.681327ZINFO(on_ac=true, battery=Some(100))2026-04-11T19:00:32.695244ZINFOscreenpipe_engine::ui_recorder: Starting UIevent capturescreenpipe_engine::ui.recorder: UI recording session started: 47668625-ff04-42f8-aa0d-f468ff11f0ff2026-04-11T19:00:32.695238ZINFOscreenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)2026-04-11T19:00:32.695298ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warming from DB(2026-04-10 16:00:32.695296 UTC to 2026-04-11 16:00:32.695296 UTC)2026-04-11T19:00:32.695769ZINFO2026-04-11T19:00:32.701263ZINFOscreenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)screenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T19:00:32.705041ZINFOscreenpipe_connect::mdns: mdns:advertising screenpipe onport 30302026-04-11T19:00:32.852998ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmedwith 880entries, coverage from 2026-04-10 16:00:32.695296 UTC2026-04-11T19:00:32.998691ZINFOscreenpipe_engine::vision_manager::manager: Starting vision recordingfor monitor 1 (1440×900)2026-04-11719:00:32.998717ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T19:00:32.998728ZINFO2026-04-11T19:00:32.998739ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed listscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T19:00:32.998790ZINFOscreenpipe_engine::event_driven_capture:event-driven capture started for monitor 1 (device: monitor_1)...
|
Firefox
|
Picture-in-Picture
|
NULL
|
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Edit prof DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Edit profile
Edit profile
How to Get Through the Product Management Bottleneck
How to Get Through the Product Management Bottleneck
Časť 3 • HBO Max
Mute tab
Časť 3 • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Maďarské voľby – Denník N
Maďarské voľby – Denník N
Vimium Options
Vimium Options
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
11
/
04
/
2026
Calendar
TOTAL SPAN
1.0h
14:52 → 15:54
ACTIVE
1.0h
BREAKS
0 breaks · 0.0h
SESSIONS
1
62m
FRAMES
612
APPS
6
UI EVENTS
1344
AUDIO
0
ACTIVE PERIOD
14:52 → 15:54
TIME PER APP
— CLICK TO FILTER RIGHT PANEL
iTerm2
5.2m
Firefox
1.5m
Finder
0.6m
QuickTime Player
0.5m
NetAuthAgent
0.1m
Raycast
0.1m
Websites
Windows
UI Events
nas.lakylak.xyz/desktop/#/
0.7m
play.hbomax.com/video/watch/6b742798-e5fa-4f90-8beb-74c328dc5028/65d19c63-e85e-4392-8594-f0f2e0a1dc2d
0.1m
nas.lakylak.xyz/desktop/#/login/account
0.1m
login.tailscale.com/login?next_url=%2Fadmin
0.1m
dennikn.sk/5263377/lod-orion-uspesne-pristala-na-zemi-desat-veci-ktore-si-pamatat-na-misii-artemis-ii/
0.1m
http://localhost:3030
0m
addons.mozilla.org/en-US/firefox/addon/vimium-ff/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0m
accounts.google.com/v3/signin/accountchooser?access_type=offline&client_id=674241127656-lmq9su4p8ni1tcpuh6eqidoornqtvmvi.apps.googleusercontent.com&prompt=select_account&redirect_uri=https%3A%2F%2Flogin.tailscale.com%2Fa%2Foauth_response&response_type=code&scope=openid+email+profile&state=tc-ftYwP8oB0urJfQZeh42KPfA&dsh=S1949714251%3A1775911302074699&o2v=2&service=lso&flowName=GeneralOAuthFlow&opparams=%253F&continue=https%3A%2F%2Faccounts.google.com%2Fsignin%2Foauth%2Fconsent%3Fauthuser%3Dunknown%26part%3DAJi8hAOOoeMJ9h1ZWE-Aau2rWQdjwJ-4Enpv6Ci-0hiDSq5jW9TsVTl1btOELm96_EZaQdgfRwBdj1zZGB_CYauRC0fkTqY_cZ35H_NcJOU2_4Ax0Gtto-fKf-nDgh4daUIBqdTh68bjSxOce25-KnK0XYdHV8mzb69bNhDZHVDj_gb42yLS6CaLOtRfvBqDUDqR3SzLMQPfBkXHhJz6IM_7wq52TLTL563ihzeGQBECsxCnD1Yk27REW5r_eZ0TNXkkAX7P1hB8gAkBKuZVXHltsgP7jvfc8R1fsuXURwjdV8kBOMOg3Reld6-0t5nB9qwgvuYCJsuo0Q7IMz9o-t41651a_Wsc0FnlTxFC_0DA-eKXtSlPZHRy9BW_O_UgliMh8Y9cnLpKZ4r9A_LwCm6flXHR1tZWe_NA_YGhQ9EYSdByTuW1hMcIXXh1Alssc0Sb9BtxZ5mPnlLjTXaWd8LEtCrsHv1HQQ%26flowName%3DGeneralOAuthFlow%26as%3DS1949714251%253A1775911302074699%26client_id%3D674241127656-lmq9su4p8ni1tcpuh6eqidoornqtvmvi.apps.googleusercontent.com%26requestPath%3D%252Fsignin%252Foauth%252Fconsent%23&app_domain=https%3A%2F%2Flogin.tailscale.com
0m...
|
Firefox
|
Screenpipe Dashboard — Personal
|
http://100.73.206.126:8766
|
|
drwx------ 1 lukas staff 16384 11 Apr 16:34 sc drwx------ 1 lukas staff 16384 11 Apr 16:34 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ touch /Volumes/screenpipe/test.txt
touch: /Volumes/screenpipe/test.txt: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ umount /Volumes/screenpipe
umount: unmount(/Volumes/screenpipe): Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ touch /Volumes/screenpipe/test.txt
touch: /Volumes/screenpipe/test.txt: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/db.sqlite
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ scp ~/.screenpipe/db.sqlite Adm1n@[IP_ADDRESS]:/volume1/screenpipe/db.sqlite
scp: dest open "/volume1/screenpipe/db.sqlite": No such file or directory
scp: failed to upload file /Users/lukas/.screenpipe/db.sqlite to /volume1/screenpipe/db.sqlite
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ scp ~/.screenpipe/db.sqlite Adm1n@[IP_ADDRESS]:/volume1/screenpipe/
scp: dest open "/volume1/screenpipe/": No such file or directory
scp: failed to upload file /Users/lukas/.screenpipe/db.sqlite to /volume1/screenpipe/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ll
total 32
drwxr-xr-x 4 root wheel 128 11 Apr 16:35 .
drwxr-xr-x 20 root wheel 640 4 Aug 2024 ..
lrwxr-xr-x 1 root wheel 1 11 Apr 11:13 Macintosh HD -> /
drwx------ 1 lukas staff 16384 11 Apr 16:34 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $clear
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: touch:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: bad pattern: unmount(/Volumes/screenpipe):
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: touch:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: cp:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: scp:
zsh: command not found: scp:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: scp:
zsh: command not found: scp:
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
zsh: command not found: total
zsh: command not found: drwxr-xr-x
zsh: command not found: drwxr-xr-x
zsh: file exists: /
zsh: command not found: drwx------
zsh: command not found: lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ clear
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ scp ~/.screenpipe/db.sqlite Adm1n@[IP_ADDRESS]:/volume1/screenpipe/db.sqlite
scp: dest open "/volume1/screenpipe/db.sqlite": No such file or directory
scp: failed to upload file /Users/lukas/.screenpipe/db.sqlite to /volume1/screenpipe/db.sqlite
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ls
Macintosh HD screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ll
total 32
drwxr-xr-x 4 root wheel 128 11 Apr 16:35 .
drwxr-xr-x 20 root wheel 640 4 Aug 2024 ..
lrwxr-xr-x 1 root wheel 1 11 Apr 11:13 Macintosh HD -> /
drwx------ 1 lukas staff 16384 11 Apr 16:34 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/db.sqlite
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/Test/screenpipe/db.sqlite
cp: /Volumes/Test/screenpipe/db.sqlite: No such file or directory
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/Test/screenpipe/
cp: directory /Volumes/Test/screenpipe does not exist
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/Test/screenpipe/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/db.sqlite
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp ~/.screenpipe/db.sqlite /Volumes/screenpipe/
cp: /Volumes/screenpipe/db.sqlite: Operation not permitted
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ll
total 96
drwxr-xr-x 6 root wheel 192 11 Apr 16:45 .
drwxr-xr-x 20 root wheel 640 4 Aug 2024 ..
drwx------ 1 lukas staff 16384 10 Aug 2025 Apps
lrwxr-xr-x 1 root wheel 1 11 Apr 11:13 Macintosh HD -> /
drwx------ 1 lukas staff 16384 11 Apr 15:46 Test
drwx------ 1 lukas staff 16384 11 Apr 16:47 screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp -r ~/.screenpipe/pipes/ /Volumes/Test/screenpipe/pipes/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cp -r ~/.screenpipe/data/data/ /Volumes/Test/screenpipe/data/
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ sed 's|$HOME/.screenpipe/db.sqlite|/volume1/Test/screenpipe/db.sqlite|g' ~/screenpipe-day.sh > /volume1/Test/screenpipe/screenpipe-day.sh
zsh: no such file or directory: /volume1/Test/screenpipe/screenpipe-day.sh
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cat ~/screenpipe-day.sh
#!/bin/zsh
DB="$HOME/.screenpipe/db.sqlite"
DATE=${1:-$(date -v-1d '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo "\n⌨️ ACTIVITY TYPE PER APP (clicks / keys / switches)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo "\n🌐 BROWSER URLS VISITED"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo "\n📋 CLIPBOARD ACTIVITY"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo "\n💬 OCR TEXT SAMPLES PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-15s %s', o.app_name, SUBSTR(o.text, 1, 80))
FROM ocr_text o
JOIN frames f ON o.frame_id = f.id
WHERE date(f.timestamp) = '$DATE' AND o.app_name IS NOT NULL AND o.text != ''
GROUP BY o.app_name
ORDER BY o.app_name LIMIT 15;"
echo "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT
'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';
"
sqlite3 "$DB" "
SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';
"
sqlite3 "$DB" "
SELECT 'OCR texts: ' || COUNT(*) FROM ocr_text o JOIN frames f ON o.frame_id = f.id WHERE date(f.timestamp) = '$DATE';
"
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ curl -X POST [URL_WITH_CREDENTIALS] /Volumes $ curl -X POST [URL_WITH_CREDENTIALS] /Volumes $ curl [URL_WITH_CREDENTIALS] /Volumes $ curl -s [URL_WITH_CREDENTIALS] /Volumes $ echo "alias sp-status='curl -s [URL_WITH_CREDENTIALS] /Volumes $ sp-status
zsh: command not found: sp-status
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ source ~/.zprofile
Poetry could not find a pyproject.toml file in /Volumes or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ sp-status
zsh: command not found: sp-status
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ zp
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ ls
Apps Macintosh HD Test screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny /Volumes $ cd
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ ll
total 1272
drwx------+ 89 lukas staff 2848 11 Apr 18:38 .
drwxr-xr-x 5 root admin 160 23 Aug 2024 ..
-r-------- 1 lukas staff 7 18 Nov 2021 .CFUserTextEncoding
-rw-r--r--@ 1 lukas staff 22532 11 Apr 16:46 .DS_Store
drwx------+ 2 lukas staff 64 11 Apr 11:15 .Trash
drwx------ 5 lukas staff 160 1 Nov 2021 .aws
-rw-r--r-- 1 lukas staff 341470 29 Sep 2022 .babel.json
-rw-------@ 1 lukas staff 388 25 Jul 2025 .bash_history
-rw-r--r--@ 1 lukas staff 77 9 Feb 2023 .bashrc
drwxr-xr-x 5 lukas staff 160 11 Mar 2023 .bito
drwx------@ 6 lukas staff 192 9 Apr 19:53 .cache
drwxr-xr-x 20 lukas staff 640 9 Apr 21:21 .claude
-rw------- 1 lukas staff 24973 9 Apr 21:24 .claude.json
drwxr-xr-x@ 20 lukas staff 640 12 Mar 09:12 .codeium
drwxrwxrwx@ 3 lukas staff 96 2 Mar 2023 .composer
drwx------ 16 lukas staff 512 21 May 2025 .config
drwxr-xr-x 15 lukas staff 480 23 Dec 2024 .continue
drwx------@ 3 lukas staff 96 16 Feb 19:13 .copilot
drwxr-xr-x@ 5 lukas staff 160 9 Apr 2025 .cursor
drwxr-xr-x@ 5 lukas staff 160 17 Aug 2024 .cursor-tutor
drwxr-xr-x 3 lukas staff 96 8 Sep 2024 .daytona
drwxr-xr-x@ 4 lukas staff 128 18 Feb 10:52 .devdb
drwx------ 24 lukas staff 768 9 Apr 18:24 .docker
drwx------ 15 lukas staff 480 6 Jun 2023 .dropbox
drwxr-xr-x@ 3 lukas staff 96 20 Nov 2022 .fig.dotfiles.bak
-rw-r--r-- 1 lukas staff 138 5 Mar 2022 .gauth
-rw-r--r-- 1 lukas staff 220 25 Nov 2021 .gitconfig
-rw-r--r-- 1 lukas staff 12288 25 Nov 2021 .gitconfig.swp
drwx------ 5 lukas staff 160 18 Nov 2021 .hammerspoon
drwxr-xr-x 3 lukas staff 96 21 Mar 2025 .idlerc
-rw------- 1 lukas staff 20 31 Mar 18:32 .lesshst
drwx------ 5 lukas staff 160 23 Dec 2024 .local
-rw------- 1 lukas staff 204 16 Mar 2024 .netrc
drwx------ 3 lukas staff 96 1 Nov 2021 .node-gyp
-rw------- 1 lukas staff 4 6 Feb 2024 .node_repl_history
-rw-r--r-- 1 lukas staff 17 24 Dec 2023 .notion-enhancer
drwxr-xr-x 4 lukas staff 128 12 Jul 2024 .notion-py
drwx------ 9 lukas staff 288 11 Apr 18:41 .npm
-rw------- 1 lukas staff 74 20 May 2024 .npmrc
drwx------ 32 lukas staff 1024 25 Jul 2025 .nvm
drwxr-xr-x 4 lukas staff 128 5 Aug 2023 .postman
-rw-r--r--@ 1 lukas staff 77 9 Feb 2023 .profile
-rw-------@ 1 lukas staff 3153 21 Mar 2025 .python_history
drwx------ 2 lukas staff 64 15 Nov 2021 .quicktype-vscode
drwxr-xr-x@ 8 lukas staff 256 16 Feb 08:48 .redis-insight
drwxr-xr-x 10 lukas staff 320 11 Apr 14:52 .screenpipe
UW PICO 5.09 New Buffer
[ Read 11 lines ]
^G Get Help ^O WriteOut ^R Read File ^Y Prev Pg ^K Cut Text ^C Cur Pos
^X Exit ^J Justify ^W Where is ^V Next Pg ^U UnCut Text ^T To Spell
drwxr-xr-x 4 lukas staff 128 4 Feb 09:35 .sonarlint
drwx------ 15 lukas staff 480 8 Aug 2025 .ssh
drwxr-xr-x@ 3 lukas staff 96 15 Aug 2025 .streamlit
drwx------ 6 lukas staff 192 17 Oct 2022 .swiftpm
-rw------- 1 lukas staff 12183 8 Apr 19:14 .viminfo
drwx------ 5 lukas staff 160 19 Jun 2023 .vscode
drwxr-xr-x@ 3 lukas staff 96 20 Jan 2025 .warp
drwxr-xr-x 4 lukas staff 128 29 Apr 2023 .wdm
drwxr-xr-x@ 5 lukas staff 160 26 Jan 13:03 .windsurf
drwxr-xr-x 4 lukas staff 128 24 Mar 12:03 .yarn
-rw-r--r-- 1 lukas staff 116 30 Mar 10:12 .yarnrc
-rw-r--r--@ 1 lukas staff 49518 6 Apr 14:31 .zcompdump
-rw-r--r--@ 1 lukas staff 46758 2 Nov 20:34 .zcompdump.Lukas-Kovaliks-MacBook-Pro-Jiminny.23381
-rw-r--r--@ 1 lukas staff 5641 9 Apr 20:30 .zprofile
-rw-r--r-- 1 lukas staff 1468 8 Apr 2022 .zprofile-copy
-rw-r--r--@ 1 lukas staff 2900 15 Mar 2023 .zprofile.pysave
-rw------- 1 lukas staff 1731 29 Jun 2022 .zprofile.save
-rw-r--r-- 1 lukas staff 1569 8 Apr 2022 .zprofilees
UW PICO 5.09 New Buffer
[ Read 13 lines ]
^G Get Help ^O WriteOut ^R Read File ^Y Prev Pg ^K Cut Text ^C Cur Pos
^X Exit ^J Justify ^W Where is ^V Next Pg ^U UnCut Text ^T To Spell
-rw------- 1 lukas staff 28812 11 Apr 18:38 .zsh_history
drwx------ 9 lukas staff 288 6 May 2025 .zsh_sessions
-rw-r--r--@ 1 lukas staff 597 11 Apr 18:44 .zshrc
drwx------@ 9 lukas staff 288 9 Apr 20:08 Applications
drwxr-xr-x@ 2 lukas staff 64 22 Oct 09:35 CascadeProjects
drwxr-xr-x 4 lukas staff 128 27 Oct 09:24 DEV
drwx------@ 10 lukas staff 320 11 Apr 18:31 Desktop
drwx------@ 7 lukas staff 224 26 Mar 14:40 Documents
drwx------@ 41 lukas staff 1312 8 Apr 20:46 Downloads
drwxr-xr-x@ 4 lukas staff 128 17 Mar 20:27 Keychron_Screen
drwx------@ 112 lukas staff 3584 2 Dec 09:19 Library
drwx------ 7 lukas staff 224 12 Feb 2024 Movies
drwx------+ 5 lukas staff 160 25 Sep 2023 Music
drwx------+ 9 lukas staff 288 25 Sep 2023 Pictures
drwx------ 3 lukas staff 96 8 Nov 2021 Postman
drwx------+ 4 lukas staff 128 28 Oct 2021 Public
-rw-r--r--@ 1 lukas staff 3950 15 Dec 09:16 Untitled 4.spf
drwx------ 4 lukas staff 128 2 Jul 2023 Users
drwx------ 3 lukas staff 96 30 Sep 2022 iCloud Drive (Archive)
drwx------ 16 lukas staff 512 3 Nov 11:35 jiminny
drwxr-xr-x 3 lukas staff 96 20 Mar 18:47 node_modules
drwxr-xr-x 4 lukas staff 128 21 Oct 18:15 raycast
-rw-r--r-- 1 lukas staff 0 1 Mar 14:26 response.bin
-rwxr-xr-x 1 lukas staff 3824 11 Apr 15:16 screenpipe-day.sh
-rw-r--r-- 1 lukas staff 86 20 Mar 18:47 yarn.lock
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ nano .zshrc
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ echo "alias sp-status='curl -s [URL_WITH_CREDENTIALS] ~ $ source ~/.zprofile
Poetry could not find a pyproject.toml file in /Users/lukas or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sp-status
{
"status": "healthy",
"frame_status": "ok",
"audio_status": "disabled",
"last_frame": "2026-04-11T18:47:17+03:00",
"uptime": 345.971219541,
"fps": 0.[CREDIT_CARD],
"frames": 34
}
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sp-stop
screenpipe stopped
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ nano ~/.screenpipe/config.json
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sp-start
[1] 41216
detected hardware tier: Mid
checking permissions...
screen recording: ok
accessibility: ok
2026-04-11T18:54:13.170097Z INFO screenpipe_screen::monitor::macos_version: Detected macOS version: 14.6
2026-04-11T18:54:13.812964Z INFO screenpipe_engine::sleep_monitor: Starting macOS sleep/wake monitor
2026-04-11T18:54:13.819889Z INFO screenpipe: meeting detector enabled — independent of transcription mode
2026-04-11T18:54:13.819889Z INFO screenpipe_engine::sleep_monitor: Screen lock/unlock observers registered (CFNotificationCenter)
2026-04-11T18:54:13.820291Z INFO screenpipe_engine::snapshot_compaction: snapshot compaction worker started (min_age=600s, poll=300s)
2026-04-11T18:54:13.820220Z INFO screenpipe_engine::power::manager: power manager started (poll interval: 10s)
2026-04-11T18:54:13.820450Z INFO screenpipe_engine::vision_manager::manager: Starting VisionManager
2026-04-11T18:54:13.820896Z INFO screenpipe_core::pipes: loaded pipe: day-recap
2026-04-11T18:54:13.820856Z INFO screenpipe_engine::sleep_monitor: Display reconfiguration watcher registered (CGDisplayRegisterReconfigurationCallback)
2026-04-11T18:54:13.821123Z INFO screenpipe_core::pipes: loaded pipe: standup-update
2026-04-11T18:54:13.821801Z INFO screenpipe_core::pipes: loaded pipe: ai-habits
2026-04-11T18:54:13.821972Z INFO screenpipe_core::pipes: loaded pipe: time-breakdown
2026-04-11T18:54:13.822128Z INFO screenpipe_core::pipes: loaded pipe: video-export
2026-04-11T18:54:13.822942Z INFO screenpipe_core::pipes: loaded pipe: meeting-summary
2026-04-11T18:54:13.822962Z INFO screenpipe_core::pipes: loaded 6 pipes from "/Users/lukas/.screenpipe/pipes"
_
__________________ ___ ____ ____ (_____ ___
/ ___/ ___/ ___/ _ \/ _ \/ __ \ / __ \/ / __ \/ _ \
(__ / /__/ / / __/ __/ / / / / /_/ / / /_/ / __/
/____/\___/_/ \___/\___/_/ /_/ / .___/_/ .___/\___/
/_/ /_/
power AI by everything you've seen, said or heard
open source | runs locally | developer friendly
┌────────────────────────┬────────────────────────────────────┐
│ setting │ value │
├────────────────────────┼────────────────────────────────────┤
│ audio chunk duration │ 30 seconds │
│ port │ 3030 │
│ audio disabled │ true │
│ vision disabled │ false │
│ pause on DRM content │ false │
│ audio engine │ Parakeet │
│ vad engine │ Silero │
│ data directory │ /Users/lukas/.screenpipe │
│ debug mode │ false │
│ telemetry │ true │
│ use pii removal │ true │
│ use all monitors │ true │
│ ignored windows │ [] │
│ included windows │ [] │
│ cloud sync │ disabled │
│ auto-destruct pid │ 0 │
│ deepgram key │ not set │
├────────────────────────┼────────────────────────────────────┤
│ languages │ │
│ │ all languages │
├────────────────────────┼────────────────────────────────────┤
│ monitors │ │
│ │ no monitors available │
├────────────────────────┼────────────────────────────────────┤
│ audio devices │ │
│ │ disabled │
└────────────────────────┴────────────────────────────────────┘
you are using local processing. all your data stays on your computer.
warning: telemetry is enabled. only error-level data will be sent.
to disable, use the --disable-telemetry flag.
check latest changes here: [URL_WITH_CREDENTIALS] ~ $ 2026-04-11T18:54:18.859011Z INFO screenpipe_engine::retention: retention: initialized with 14d retention
2026-04-11T18:54:18.859467Z INFO screenpipe: local retention auto-enabled (14 days)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sp-stop
screenpipe stopped
[1] + terminated npx screenpipe@latest record --disable-audio
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ sqlite3 ~/.screenpipe/db.sqlite "
SELECT DISTINCT window_name
FROM frames
WHERE app_name IN ('Safari', 'Firefox', 'Arc', 'Chrome')
AND window_name IS NOT NULL
UW PICO 5.09 New Buffer
[ Read 13 lines ]
^G Get Help ^O WriteOut ^R Read File ^Y Prev Pg ^K Cut Text ^C Cur Pos
^X Exit ^J Justify ^W Where is ^V Next Pg ^U UnCut Text ^T To Spell
ORDER BY window_name;"
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8 — Personal
Denník N - Nezávislý denník — Personal
Edit profile — Personal
Location Logger
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N — Personal
Maďarské voľby – Denník N — Personal
Personal — Mozilla Firefox
Picture-in-Picture
Problem loading page — Personal
Screenpipe Dashboard — Personal
Settings — Personal
Sign in – Google accounts — Personal
Tailscale — Personal
UGREEN NAS — Personal
Vimium Options — Personal
Vimium – Get this Extension for 🦊 Firefox (en-US) — Personal
firefox sidebar - Google Search — Personal
tilscale admin panel - Google Search — Personal
Order Room Service • HBO Max
Shameless • HBO Max
Shameless • HBO Max — Personal
Simple Pleasures • HBO Max — Personal
Časť 2 • HBO Max — Personal
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ cat ~/.screenpipe/config.json
{
"disable_audio": true,
"monitor_ids": ["Display 1_1440x900_0,0", "Display 2_3008x1253_-813,-1253"],
"ignored_windows": [
"1Password",
"Keychain Access",
"Bitwarden",
"System Preferences",
"System Settings",
"zoom.us",
"HBO Max",
]
}
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ nano ~/.screenpipe/config.json
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ pkill screenpipe && sleep 2 && npx screenpipe@latest record
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ pkill screenpipe
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ npx screenpipe@latest record
detected hardware tier: Mid
checking permissions...
screen recording: ok
microphone: ok
accessibility: ok
2026-04-11T19:00:06.546722Z INFO screenpipe_screen::monitor::macos_version: Detected macOS version: 14.6
2026-04-11T19:00:07.267955Z INFO screenpipe_engine::sleep_monitor: Starting macOS sleep/wake monitor
2026-04-11T19:00:07.269566Z INFO screenpipe: meeting detector enabled — independent of transcription mode
2026-04-11T19:00:07.269564Z INFO screenpipe_engine::sleep_monitor: Screen lock/unlock observers registered (CFNotificationCenter)
2026-04-11T19:00:07.269921Z INFO screenpipe_engine::sleep_monitor: Display reconfiguration watcher registered (CGDisplayRegisterReconfigurationCallback)
2026-04-11T19:00:07.470439Z INFO screenpipe_engine::snapshot_compaction: snapshot compaction worker started (min_age=600s, poll=300s)
2026-04-11T19:00:07.470481Z INFO screenpipe_engine::vision_manager::manager: Starting VisionManager
2026-04-11T19:00:07.470420Z INFO screenpipe_engine::power::manager: power manager started (poll interval: 10s)
2026-04-11T19:00:07.470877Z INFO screenpipe_core::pipes: loaded pipe: day-recap
2026-04-11T19:00:07.471071Z INFO screenpipe_core::pipes: loaded pipe: standup-update
2026-04-11T19:00:07.471748Z INFO screenpipe_core::pipes: loaded pipe: ai-habits
2026-04-11T19:00:07.471948Z INFO screenpipe_core::pipes: loaded pipe: time-breakdown
2026-04-11T19:00:07.472085Z INFO screenpipe_core::pipes: loaded pipe: video-export
2026-04-11T19:00:07.472295Z INFO screenpipe_core::pipes: loaded pipe: meeting-summary
2026-04-11T19:00:07.472315Z INFO screenpipe_core::pipes: loaded 6 pipes from "/Users/lukas/.screenpipe/pipes"
_
__________________ ___ ____ ____ (_____ ___
/ ___/ ___/ ___/ _ \/ _ \/ __ \ / __ \/ / __ \/ _ \
(__ / /__/ / / __/ __/ / / / / /_/ / / /_/ / __/
/____/\___/_/ \___/\___/_/ /_/ / .___/_/ .___/\___/
/_/ /_/
power AI by everything you've seen, said or heard
open source | runs locally | developer friendly
┌────────────────────────┬────────────────────────────────────┐
│ setting │ value │
├────────────────────────┼────────────────────────────────────┤
│ audio chunk duration │ 30 seconds │
│ port │ 3030 │
│ audio disabled │ false │
│ vision disabled │ false │
│ pause on DRM content │ false │
│ audio engine │ Parakeet │
│ vad engine │ Silero │
│ data directory │ /Users/lukas/.screenpipe │
│ debug mode │ false │
│ telemetry │ true │
│ use pii removal │ true │
│ use all monitors │ true │
│ ignored windows │ [] │
│ included windows │ [] │
│ cloud sync │ disabled │
│ auto-destruct pid │ 0 │
│ deepgram key │ not set │
├────────────────────────┼────────────────────────────────────┤
│ languages │ │
│ │ all languages │
├────────────────────────┼────────────────────────────────────┤
│ monitors │ │
│ │ no monitors available │
├────────────────────────┼────────────────────────────────────┤
│ audio devices │ │
│ │ soundcore AeroClip (input) │
│ │ System Audio (output) │
└────────────────────────┴────────────────────────────────────┘
you are using local processing. all your data stays on your computer.
warning: telemetry is enabled. only error-level data will be sent.
to disable, use the --disable-telemetry flag.
check latest changes here: [URL_WITH_CREDENTIALS] ~ $ 2026-04-11T19:00:14.624523Z INFO screenpipe_engine::ui_recorder: UI recording session ended: 6b15bcb7-6588-4b6b-9ae5-5a3b50fba2a2
2026-04-11T19:00:14.624669Z INFO screenpipe: shutdown complete
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ npx screenpipe@latest record
detected hardware tier: Mid
checking permissions...
screen recording: ok
microphone: ok
accessibility: ok
2026-04-11T19:00:31.694964Z INFO screenpipe_screen::monitor::macos_version: Detected macOS version: 14.6
2026-04-11T19:00:32.442217Z INFO screenpipe_engine::sleep_monitor: Starting macOS sleep/wake monitor
2026-04-11T19:00:32.443687Z INFO screenpipe: meeting detector enabled — independent of transcription mode
2026-04-11T19:00:32.443694Z INFO screenpipe_engine::sleep_monitor: Screen lock/unlock observers registered (CFNotificationCenter)
2026-04-11T19:00:32.444120Z INFO screenpipe_engine::sleep_monitor: Display reconfiguration watcher registered (CGDisplayRegisterReconfigurationCallback)
2026-04-11T19:00:32.662907Z INFO screenpipe_engine::snapshot_compaction: snapshot compaction worker started (min_age=600s, poll=300s)
2026-04-11T19:00:32.662887Z INFO screenpipe_engine::power::manager: power manager started (poll interval: 10s)
2026-04-11T19:00:32.662980Z INFO screenpipe_engine::vision_manager::manager: Starting VisionManager
2026-04-11T19:00:32.663355Z INFO screenpipe_core::pipes: loaded pipe: day-recap
2026-04-11T19:00:32.663550Z INFO screenpipe_core::pipes: loaded pipe: standup-update
2026-04-11T19:00:32.664216Z INFO screenpipe_core::pipes: loaded pipe: ai-habits
2026-04-11T19:00:32.664395Z INFO screenpipe_core::pipes: loaded pipe: time-breakdown
2026-04-11T19:00:32.664552Z INFO screenpipe_core::pipes: loaded pipe: video-export
2026-04-11T19:00:32.665488Z INFO screenpipe_core::pipes: loaded pipe: meeting-summary
2026-04-11T19:00:32.665515Z INFO screenpipe_core::pipes: loaded 6 pipes from "/Users/lukas/.screenpipe/pipes"
_
__________________ ___ ____ ____ (_____ ___
/ ___/ ___/ ___/ _ \/ _ \/ __ \ / __ \/ / __ \/ _ \
(__ / /__/ / / __/ __/ / / / / /_/ / / /_/ / __/
/____/\___/_/ \___/\___/_/ /_/ / .___/_/ .___/\___/
/_/ /_/
power AI by everything you've seen, said or heard
open source | runs locally | developer friendly
┌────────────────────────┬────────────────────────────────────┐
│ setting │ value │
├────────────────────────┼────────────────────────────────────┤
│ audio chunk duration │ 30 seconds │
│ port │ 3030 │
│ audio disabled │ false │
│ vision disabled │ false │
│ pause on DRM content │ false │
│ audio engine │ Parakeet │
│ vad engine │ Silero │
│ data directory │ /Users/lukas/.screenpipe │
│ debug mode │ false │
│ telemetry │ true │
│ use pii removal │ true │
│ use all monitors │ true │
│ ignored windows │ [] │
│ included windows │ [] │
│ cloud sync │ disabled │
│ auto-destruct pid │ 0 │
│ deepgram key │ not set │
├────────────────────────┼────────────────────────────────────┤
│ languages │ │
│ │ all languages │
├────────────────────────┼────────────────────────────────────┤
│ monitors │ │
│ │ no monitors available │
├────────────────────────┼────────────────────────────────────┤
│ audio devices │ │
│ │ soundcore AeroClip (input) │
│ │ System Audio (output) │
└────────────────────────┴────────────────────────────────────┘
you are using local processing. all your data stays on your computer.
warning: telemetry is enabled. only error-level data will be sent.
to disable, use the --disable-telemetry flag.
check latest changes here: https://github.com/screenpipe/screenpipe/releases
2026-04-11T19:00:32.667186Z INFO screenpipe_core::pipes: pipe scheduler started (generation 2)
2026-04-11T19:00:32.667286Z INFO screenpipe: starting UI event capture
2026-04-11T19:00:32.670076Z WARN screenpipe: pi agent install failed: bun not found — install from https://bun.sh
2026-04-11T19:00:32.672989Z INFO screenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))
2026-04-11T19:00:32.681327Z INFO screenpipe_engine::ui_recorder: Starting UI event capture
2026-04-11T19:00:32.695244Z INFO screenpipe_engine::ui_recorder: UI recording session started: 47668625-ff04-42f8-aa0d-f468ff11f0ff
2026-04-11T19:00:32.695238Z INFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)
2026-04-11T19:00:32.695298Z INFO screenpipe_engine::hot_frame_cache: hot_frame_cache: warming from DB (2026-04-10 16:00:32.695296 UTC to 2026-04-11 16:00:32.695296 UTC)
2026-04-11T19:00:32.695769Z INFO screenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)
2026-04-11T19:00:32.701263Z INFO screenpipe_engine::server: Server listening on [IP_ADDRESS]:3030
2026-04-11T19:00:32.705041Z INFO screenpipe_connect::mdns: mdns: advertising screenpipe on port 3030
2026-04-11T19:00:32.852998Z INFO screenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 880 frame entries, coverage from 2026-04-10 16:00:32.695296 UTC
2026-04-11T19:00:32.998691Z INFO screenpipe_engine::vision_manager::manager: Starting vision recording for monitor 1 (1440x900)
2026-04-11T19:00:32.998717Z INFO screenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)
2026-04-11T19:00:32.998728Z INFO screenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) — not in allowed list
2026-04-11T19:00:32.998739Z INFO screenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)
2026-04-11T19:00:32.998790Z INFO screenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)
2026-04-11T19:00:33.736410Z INFO sck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)
2026-04-11T19:00:34.302357Z INFO screenpipe_engine::event_driven_capture: startup capture for monitor 1: frame_id=1404, dur=507ms
2026-04-11T19:00:37.699366Z INFO screenpipe_engine::retention: retention: initialized with 14d retention
2026-04-11T19:00:37.699830Z INFO screenpipe: local retention auto-enabled (14 days)
DOCKER
Close Tab
DEV (-zsh)
Close Tab...
|
iTerm2
|
screenpipe"
|
NULL
|
|
Cannot reconnect. Please reload the window.
Reload Cannot reconnect. Please reload the window.
Reload Window
Cancel
iTerm2ShellEditViewSessionScriptsProfilesWindowHelp-zshDOCKER• 881vad enginedata directorydebug modetelemetryuse pii removaluse all monitorsignored windowsincluded windowscloud syncauto-destruct piddeepgram keyLanguagesmonitorsaudio devicesDEV (-zsh)О 82Silero/Users/lukas/.screenpipefalsetruetruetruedisablednot setall languagesAPP (-zsh)• *3-zsh• ×4-zsh• ₴5|$0(ahl-zsh886-zsh100% <7O 87Sat 11 Apr 20:26:06-zshT81• *8|no monitors availabledisabledyou are using local processing. all your data stays on your computer.warning: telemetry isenabled. onlyerror-levelto disable, usethe --disable-telemetry flag.data will be sent.check latestchanges here:https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFOscreenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.348754ZINFOscreenpipe:starting UIevent capture2026-04-11T20:26:05.353656ZWARNscreenpipe:piagent install failed: bun not found - install from https://bun.sh2026-04-11T20:26:05.3585402INFOscreenpipe_engine::power::manager:initial power profile: Performance2026-04-11T20:26:05.363864ZINFO(on_ac=true, battery=Some(100))screenpipe_engine::ui_recorder: Starting UIevent capture2026-04-11T20:26:05.378325ZINFOscreenpipe_engine::calendar_speaker_id:speakeridentification: started (user_name=<not set>)2026-04-11T20:26:05.3783922INFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warming from DB(2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFO2026-04-11T20:26:05.384798ZINFOscreenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)screenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns:advertising screenpipe onport 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting vision recordingfor monitor 1 (1440×900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFO2026-04-11T20:26:05.683311Zscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed listINFOscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.6833592INFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)...
|
Code
|
|
NULL
|
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Časť 3 DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Časť 3 • HBO Max
Časť 3 • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Irán – Denník N
Irán – Denník N
Vimium Options
Vimium Options
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Search results for "bitwarden" – Add-ons for Firefox (en-US)
Search results for "bitwarden" – Add-ons for Firefox (en-US)
New Tab
New Tab
Close tab
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Browser Extension Getting Started | Bitwarden
Browser Extension Getting Started | Bitwarden
Extensions – Add-ons for Firefox (en-US)
Extensions – Add-ons for Firefox (en-US)
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
22°
C
New York City
Open menu
Do you want to see the weather for your location?
Do you want to see the weather for your location?
Not now
Not now
Yes
Yes
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Inbox - [EMAIL] - Gmail
Inbox - [EMAIL] - Gmail
Open context menu for Inbox - [EMAIL] - Gmail
UGREEN NAS
UGREEN NAS
Open context menu for UGREEN NAS
Časť 2 • HBO Max
Časť 2 • HBO Max
Open context menu for Časť 2 • HBO Max
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Open context menu for Vimium – Get this Extension for 🦊 Firefox (en-US)
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Open context menu for How to use AI-enhanced tab groups | Firefox Help
Screenpipe Dashboard
Screenpipe Dashboard
Open context menu for Screenpipe Dashboard
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Open context menu for Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Wikipedia
Wikipedia
Open context menu for Wikipedia
Customize
Customize...
|
Firefox
|
Personal — Mozilla Firefox
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp-zshDOCKER• 881use all monitorsignored windowsincluded windowscloud syncauto-destruct piddeepgram keylanguagesDEV (-zsh)truedisablednot setO 82APP (-zsh)• *3-zsh• *4-zsh• 285$0(ahl-zsh886-zsh100% <7O 87Sat 11 Apr 20:26:11-zsh181• *8all languagesmonitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry is enabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes: pipe scheduler started (generation 2)2026-04-11T20:26:05.348754ZINFOscreenpipe:starting UIevent capture2026-04-11T20:26:05.353656ZWARNscreenpipe:2026-04-11T20:26:05.358540ZINFOpiagent install failed: bun notfound- install from https://bun.shscreenpipe_engine::power::manager:initialpower profile:Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.3638642INFOscreenpipe_engine::ui_recorder: Starting UIeventcapture2026-04-11T20:26:05.378325ZINFOscreenpipe_engine::calendar_speaker_id: speaker identification: started(user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB (2026-04-10 17:26:05.378561 UTC to 2026-04-1117:26:05.378561 UTC)2026-04-11720:26:05.3794672INFO2026-04-11T20:26:05.384798Zscreenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)INFOscreenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipeon port 30302026-04-11T20:26:05.5281072INFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting vision recording for monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed list2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager:persistentSCK stream started for display 1 (1440x900,2fps)2026-04-11T20:26:07.067446ZINFOscreenpipe_engine::event_driven_capture: startupcapture for monitor 1:2026-04-11T20:26:08.752985ZINFOtrame_1d=140r, aur=33/msscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=-9215443531147982391, trigger=visual_change)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFO screenpipe: local retention auto-enabled (14 days)...
|
NULL
|
NULL
|
NULL
|
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Irán – Denník N
Irán – Denník N
Vimium Options
Vimium Options
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Search results for "bitwarden" – Add-ons for Firefox (en-US)
Search results for "bitwarden" – Add-ons for Firefox (en-US)
New Tab
New Tab
Close tab
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Browser Extension Getting Started | Bitwarden
Browser Extension Getting Started | Bitwarden
Extensions – Add-ons for Firefox (en-US)
Extensions – Add-ons for Firefox (en-US)
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
22°
C
New York City
Open menu
Do you want to see the weather for your location?
Do you want to see the weather for your location?
Not now
Not now
Yes
Yes
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Inbox - [EMAIL] - Gmail
Inbox - [EMAIL] - Gmail
Open context menu for Inbox - [EMAIL] - Gmail
UGREEN NAS
UGREEN NAS
Open context menu for UGREEN NAS
Časť 2 • HBO Max
Časť 2 • HBO Max
Open context menu for Časť 2 • HBO Max
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Open context menu for Vimium – Get this Extension for 🦊 Firefox (en-US)
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Open context menu for How to use AI-enhanced tab groups | Firefox Help
Screenpipe Dashboard
Screenpipe Dashboard
Open context menu for Screenpipe Dashboard
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Open context menu for Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Wikipedia
Wikipedia
Open context menu for Wikipedia
Customize
Customize...
|
Firefox
|
Personal — Mozilla Firefox
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp-zshDOCKER• 881use all monitorsignored windowsincluded windowscloud syncauto-destruct piddeepgram keylanguagesDEV (-zsh)truedisablednot setO 82APP (-zsh)• *3-zsh• *4-zsh• 285$0(ahl-zsh886-zsh100% <7O 87Sat 11 Apr 20:26:16-zshT81• *8all languagesmonitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry is enabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes: pipe scheduler started (generation 2)2026-04-11T20:26:05.348754ZINFOscreenpipe:starting UIevent capture2026-04-11T20:26:05.353656ZWARNscreenpipe:2026-04-11T20:26:05.358540ZINFOpiagent install failed: bun notfound- install from https://bun.shscreenpipe_engine::power::manager:initialpower profile:Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.3638642INFOscreenpipe_engine::ui_recorder: Starting UIeventcapture2026-04-11T20:26:05.378325ZINFOscreenpipe_engine::calendar_speaker_id: speaker identification: started(user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB (2026-04-10 17:26:05.378561 UTC to 2026-04-1117:26:05.378561 UTC)2026-04-11720:26:05.3794672INFO2026-04-11T20:26:05.384798Zscreenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)INFOscreenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipeon port 30302026-04-11T20:26:05.5281072INFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting vision recording for monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed list2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager:persistentSCK stream started for display 1 (1440x900,2fps)2026-04-11T20:26:07.067446ZINFOscreenpipe_engine::event_driven_capture: startupcapture for monitor 1:2026-04-11T20:26:08.752985ZINFOtrame_1d=140r, aur=33/msscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=-9215443531147982391, trigger=visual_change)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFO screenpipe: local retention auto-enabled (14 days)...
|
NULL
|
NULL
|
NULL
|
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Irán – Denník N
Irán – Denník N
Vimium Options
Vimium Options
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Search results for "bitwarden" – Add-ons for Firefox (en-US)
Search results for "bitwarden" – Add-ons for Firefox (en-US)
New Tab
New Tab
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Browser Extension Getting Started | Bitwarden
Browser Extension Getting Started | Bitwarden
Extensions – Add-ons for Firefox (en-US)
Extensions – Add-ons for Firefox (en-US)
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
1.8
MB/s
54.9
KB/s
Files
Control Panel
Storage
App Center
Logs
Support
Task Manager
Universal Search
Music
Cloud Drives
Theater
Photos
Online Office
TextEdit
Virtual Machine
Downloads
DLNA
File Version Explorer
Security
Jellyfin-HT
SAN Manager
Vault
Snapshot
Comics
Sync & Backup...
|
Firefox
|
DXP4800PLUS-B5F8 — Personal
|
nas.lakylak.xyz/desktop/#/
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp-zshDOCKER• 881use all monitorsignored windowsincluded windowscloud syncauto-destruct piddeepgram keylanguagesDEV (-zsh)truedisablednot setO 82APP (-zsh)• *3-zsh• *4-zsh• 285$0(ahl-zsh886-zsh100% <7O 87Sat 11 Apr 20:26:21-zshT81• *8all languagesmonitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry is enabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes: pipe scheduler started (generation 2)2026-04-11T20:26:05.348754ZINFOscreenpipe:starting UIevent capture2026-04-11T20:26:05.353656ZWARNscreenpipe:2026-04-11T20:26:05.358540ZINFOpiagent install failed: bun notfound- install from https://bun.shscreenpipe_engine::power::manager:initialpower profile:Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.3638642INFOscreenpipe_engine::ui_recorder: Starting UIeventcapture2026-04-11T20:26:05.378325ZINFOscreenpipe_engine::calendar_speaker_id: speaker identification: started(user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB (2026-04-10 17:26:05.378561 UTC to 2026-04-1117:26:05.378561 UTC)2026-04-11720:26:05.3794672INFO2026-04-11T20:26:05.384798Zscreenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)INFOscreenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipeon port 30302026-04-11T20:26:05.5281072INFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting vision recording for monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed list2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager:persistentSCK stream started for display 1 (1440x900,2fps)2026-04-11T20:26:07.067446ZINFOscreenpipe_engine::event_driven_capture: startupcapture for monitor 1:2026-04-11T20:26:08.752985ZINFOtrame_1d=140r, aur=33/msscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=-9215443531147982391, trigger=visual_change)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFO screenpipe: local retention auto-enabled (14 days)...
|
NULL
|
NULL
|
NULL
|
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Irán – Denník N
Irán – Denník N
Vimium Options
Vimium Options
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Search results for "bitwarden" – Add-ons for Firefox (en-US)
Search results for "bitwarden" – Add-ons for Firefox (en-US)
New Tab
New Tab
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Browser Extension Getting Started | Bitwarden
Browser Extension Getting Started | Bitwarden
Extensions – Add-ons for Firefox (en-US)
Extensions – Add-ons for Firefox (en-US)
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
1.8
MB/s
54.9
KB/s
Files
Control Panel
Storage
App Center
Logs
Support
Task Manager
Universal Search
Music
Cloud Drives
Theater
Photos
Online Office
TextEdit
Virtual Machine
Downloads
DLNA
File Version Explorer
Security
Jellyfin-HT
SAN Manager
Vault
Snapshot
Comics
Sync & Backup
Control Panel
Search...
|
Firefox
|
DXP4800PLUS-B5F8 — Personal
|
nas.lakylak.xyz/desktop/#/
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp-zshDOCKER• 881use all monitorsignored windowsincluded windowscloud syncauto-destruct piddeepgram keylanguagesDEV (-zsh)truedisablednot setO 82APP (-zsh)• *3-zsh• *4-zsh• 285$0(ahl-zsh886-zsh100% <7O 87Sat 11 Apr 20:26:25-zshT81• *8all languagesmonitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry is enabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes: pipe scheduler started (generation 2)2026-04-11T20:26:05.348754ZINFOscreenpipe:starting UIevent capture2026-04-11T20:26:05.353656ZWARNscreenpipe:2026-04-11T20:26:05.358540ZINFOpiagent install failed: bun notfound- install from https://bun.shscreenpipe_engine::power::manager:initialpower profile:Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.3638642INFOscreenpipe_engine::ui_recorder: Starting UIeventcapture2026-04-11T20:26:05.378325ZINFOscreenpipe_engine::calendar_speaker_id: speaker identification: started(user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB (2026-04-10 17:26:05.378561 UTC to 2026-04-1117:26:05.378561 UTC)2026-04-11720:26:05.3794672INFO2026-04-11T20:26:05.384798Zscreenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)INFOscreenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipeon port 30302026-04-11T20:26:05.5281072INFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting vision recording for monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed list2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager:persistentSCK stream started for display 1 (1440x900,2fps)2026-04-11T20:26:07.067446ZINFOscreenpipe_engine::event_driven_capture: startupcapture for monitor 1:2026-04-11T20:26:08.752985ZINFOtrame_1d=140r, aur=33/msscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=-9215443531147982391, trigger=visual_change)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFO screenpipe: local retention auto-enabled (14 days)...
|
NULL
|
NULL
|
NULL
|
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Irán – Denník N
Irán – Denník N
Vimium Options
Vimium Options
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Search results for "bitwarden" – Add-ons for Firefox (en-US)
Search results for "bitwarden" – Add-ons for Firefox (en-US)
New Tab
New Tab
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Browser Extension Getting Started | Bitwarden
Browser Extension Getting Started | Bitwarden
Extensions – Add-ons for Firefox (en-US)
Extensions – Add-ons for Firefox (en-US)
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
0
B/s
0
B/s
Files
Control Panel
Storage
App Center
Logs
Support
Task Manager
Universal Search
Music
Cloud Drives
Theater
Photos
Online Office
TextEdit
Virtual Machine
Downloads
DLNA
File Version Explorer
Security
Jellyfin-HT
SAN Manager
Vault
Snapshot
Comics
Sync & Backup
Control Panel
Search
Connection & Access
User Management
File Service
Device Connection
Domain/LDAP
Terminal
General
Hardware & Power
Time & Language
Network
Security
Indexing Service
Service
About
Update & Restore
Telnet
Enable
Enable
Port
23
Advanced settings
SSH
Enable
Enable
Port
22
Shut down automatically
3h later
Advanced settings
Function description
Use a terminal to log in and manage your system. When enabling this function, it is recommended to set a strong password for the login account and enable
auto block
auto block
to enhance system security.
Apply
Tips
Tips
SSH possesses advanced remote management feature, but enabling it for a long term will increase security risks (e.g. potential unauthorized access). To ensure NAS and data security, please only enable SSH when in need
Cancel
Enable...
|
Firefox
|
DXP4800PLUS-B5F8 — Personal
|
nas.lakylak.xyz/desktop/#/
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp-zshDOCKER• 881use all monitorsignored windowsincluded windowscloud syncauto-destruct piddeepgram keylanguagesDEV (-zsh)truedisablednot setO 82APP (-zsh)• *3-zsh• *4-zsh• 285$0(ahl-zsh886-zsh100% <7O 87Sat 11 Apr 20:26:27-zshT81• *8all languagesmonitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry is enabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes: pipe scheduler started (generation 2)2026-04-11T20:26:05.348754ZINFOscreenpipe:starting UIevent capture2026-04-11T20:26:05.353656ZWARNscreenpipe:2026-04-11T20:26:05.358540ZINFOpiagent install failed: bun notfound- install from https://bun.shscreenpipe_engine::power::manager:initialpower profile:Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.3638642INFOscreenpipe_engine::ui_recorder: Starting UIeventcapture2026-04-11T20:26:05.378325ZINFOscreenpipe_engine::calendar_speaker_id: speaker identification: started(user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB (2026-04-10 17:26:05.378561 UTC to 2026-04-1117:26:05.378561 UTC)2026-04-11720:26:05.3794672INFO2026-04-11T20:26:05.384798Zscreenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)INFOscreenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipeon port 30302026-04-11T20:26:05.5281072INFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting vision recording for monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed list2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager:persistentSCK stream started for display 1 (1440x900,2fps)2026-04-11T20:26:07.067446ZINFOscreenpipe_engine::event_driven_capture: startupcapture for monitor 1:2026-04-11T20:26:08.752985ZINFOtrame_1d=140r, aur=33/msscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=-9215443531147982391, trigger=visual_change)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFO screenpipe: local retention auto-enabled (14 days)...
|
NULL
|
NULL
|
NULL
|
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Irán – Denník N
Irán – Denník N
Vimium Options
Vimium Options
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Search results for "bitwarden" – Add-ons for Firefox (en-US)
Search results for "bitwarden" – Add-ons for Firefox (en-US)
New Tab
New Tab
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Browser Extension Getting Started | Bitwarden
Browser Extension Getting Started | Bitwarden
Extensions – Add-ons for Firefox (en-US)
Extensions – Add-ons for Firefox (en-US)
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
0
B/s
0
B/s
Files
Control Panel
Storage
App Center
Logs
Support
Task Manager
Universal Search
Music
Cloud Drives
Theater
Photos
Online Office
TextEdit
Virtual Machine
Downloads
DLNA
File Version Explorer
Security
Jellyfin-HT
SAN Manager
Vault
Snapshot
Comics
Sync & Backup
Control Panel
Search
Connection & Access
User Management
File Service
Device Connection
Domain/LDAP
Terminal
General
Hardware & Power
Time & Language
Network
Security
Indexing Service
Service
About
Update & Restore
Telnet
Enable
Enable
Port
23
Advanced settings
SSH
Enable
Enable
Port
22
Shut down automatically
30 min later
Advanced settings
Function description
Use a terminal to log in and manage your system. When enabling this function, it is recommended to set a strong password for the login account and enable
auto block
auto block
to enhance system security....
|
Firefox
|
DXP4800PLUS-B5F8 — Personal
|
nas.lakylak.xyz/desktop/#/
|
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Irán – Denník N
Irán – Denník N
Vimium Options
Vimium Options
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Search results for "bitwarden" – Add-ons for Firefox (en-US)
Search results for "bitwarden" – Add-ons for Firefox (en-US)
New Tab
New Tab
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Browser Extension Getting Started | Bitwarden
Browser Extension Getting Started | Bitwarden
Extensions – Add-ons for Firefox (en-US)
Extensions – Add-ons for Firefox (en-US)
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
11
/
04
/
2026
Calendar
Generate Report
No AI needed — pure data
📅 SESSION — 2026-04-11
📅 SESSION — 2026-04-11
14:52
START
15:54
END
1.0h
TOTAL SPAN
1.0h
ACTIVE
0.0h
BREAKS (0)
🖥️ APP TIME BY CATEGORY
🖥️ APP TIME BY CATEGORY
💻 code
5.2m total
iTerm2
5.2m
🌐 browser
1.5m total
Firefox
1.5m
🎬 media
0.5m total
QuickTime Player
0.5m
⚙️ system
0.8m total
Finder
0.6m
NetAuthAgent
0.1m
Raycast
0.1m
🌐 WEBSITES BY DOMAIN
🌐 WEBSITES BY DOMAIN
nas.lakylak.xyz/desktop/#/
nas.lakylak.xyz/desktop/#/
0.7m
play.hbomax.com/video/watch/6b742798-e5f
play.hbomax.com/video/watch/6b742798-e5fa-4f90-8beb-74c328dc5028/65d19c63-e85e-4392-8594-f
0.1m
nas.lakylak.xyz/desktop/#/login/account
nas.lakylak.xyz/desktop/#/login/account
0.1m
login.tailscale.com/login?next_url=%2Fad
login.tailscale.com/login?next_url=%2Fadmin
0.1m
dennikn.sk/5263377/lod-orion-uspesne-pri
dennikn.sk/5263377/lod-orion-uspesne-pristala-na-zemi-desat-veci-ktore-si-pamatat-na-misii
0.1m
localhost:3030
http://localhost:3030
0m
addons.mozilla.org/en-US/firefox/addon/v
addons.mozilla.org/en-US/firefox/addon/vimium-ff/?utm_source=addons.mozilla.org&utm_medium
0m
accounts.google.com/v3/signin/accountcho
accounts.google.com/v3/signin/accountchooser?access_type=offline&client_id=674241127656-lm
0m
⌨️ UI ACTIVITY (CLICKS / KEYSTROKES / APP SWITCHES)
⌨️ UI ACTIVITY (CLICKS / KEYSTROKES / APP SWITCHES)
APP
CLICKS
KEYS
SWITCHES
TOTAL
iTerm2
399
200
4
603
Firefox
79
20
4
103
Finder
90
4
5
99
NetAuthAgent
12
0
3
15
APP
iTerm2
Firefox
Finder
NetAuthAgent
CLICKS
399
79
90
12
KEYS
200
20
4
0
SWITCHES
4
4
5
3
TOTAL
603
103
99
15...
|
Firefox
|
Screenpipe Dashboard — Personal
|
http://100.73.206.126:8766
|
|
Cannot reconnect. Please reload the window.
Reload Cannot reconnect. Please reload the window.
Reload Window
Cancel
iTerm2ShellEditViewSessionScriptsProfilesWindowHelp-zshDOCKER• 881use all monitorsignored windowsincluded windowscloud syncauto-destruct piddeepgram keylanguagesDEV (-zsh)truedisablednot setO 82APP (-zsh)• *3-zsh• *4-zsh• 285$0(ahl-zsh886-zsh100% <7O 87Sat 11 Apr 20:26:37-zshT81• *8all languagesmonitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry is enabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes: pipe scheduler started (generation 2)2026-04-11T20:26:05.348754ZINFOscreenpipe:starting UIevent capture2026-04-11T20:26:05.353656ZWARNscreenpipe:2026-04-11T20:26:05.358540ZINFOpiagent install failed: bun notfound- install from https://bun.shscreenpipe_engine::power::manager:initialpower profile:Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.3638642INFOscreenpipe_engine::ui_recorder: Starting UIeventcapture2026-04-11T20:26:05.378325ZINFOscreenpipe_engine::calendar_speaker_id: speaker identification: started(user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB (2026-04-10 17:26:05.378561 UTC to 2026-04-1117:26:05.378561 UTC)2026-04-11720:26:05.3794672INFO2026-04-11T20:26:05.384798Zscreenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)INFOscreenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipeon port 30302026-04-11T20:26:05.5281072INFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting vision recording for monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed list2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager:persistentSCK stream started for display 1 (1440x900,2fps)2026-04-11T20:26:07.067446ZINFOscreenpipe_engine::event_driven_capture: startupcapture for monitor 1:2026-04-11T20:26:08.752985ZINFOtrame_1d=140r, aur=33/msscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=-9215443531147982391, trigger=visual_change)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFO screenpipe: local retention auto-enabled (14 days)...
|
Code
|
|
NULL
|
|
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update, 1 requires restart
3
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
SCREENPIPE [SSH: [IP_ADDRESS]]
#recycle
app
consumers
static
.env
cli.py
db.py
docker-compose.yml
Dockerfile
main.py
requirements.txt
data
pipes
ai-habits
pipe.md
day-recap
meeting-summary
standup-update
time-breakdown
video-export
db.sqlite
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
pipe.md, Editor Group 1
#!/bin/bash • Untitled-1, Editor Group 1
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: [IP_ADDRESS]
SSH: [IP_ADDRESS]
No Problems
0
0
No Ports Forwarded
0
Update is ready, click to restart.
Update is ready, click to restart.
Notifications
Sign In
Sign In
Shell Script
Editor Language Status: $(copilot) No inline suggestion available, Inline suggestions
LF
UTF-8
Spaces: 2
Ln 8, Col 1
Screen Reader Optimized
Info: Setting up SSH Host [IP_ADDRESS]: Setting up SSH tunnel...
|
Code
|
#!/bin/bash • Untitled-1 — screenpipe [SSH: 100.73 #!/bin/bash • Untitled-1 — screenpipe [SSH: 100.73.206.126]...
|
NULL
|
|
By continuing, you agree to GitHub's
Terms
Ter By continuing, you agree to GitHub's
Terms
Terms
and
Privacy Statement
Privacy Statement
. GitHub Copilot may show
public code
public code
suggestions and use your data to improve the product. You can change these
settings
settings
anytime.
Continue with GitHub
Continue with Google
Continue with Apple
Continue with GHE.com
Sign in to use AI Features...
|
Code
|
#!/bin/bash • Untitled-1 — screenpipe [SSH: 100.73 #!/bin/bash • Untitled-1 — screenpipe [SSH: 100.73.206.126]...
|
NULL
|
|
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update, 1 requires restart
3
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
SCREENPIPE [SSH: [IP_ADDRESS]]
#recycle
app
consumers
static
.env
cli.py
db.py
docker-compose.yml
Dockerfile
main.py
requirements.txt
data
pipes
ai-habits
pipe.md
day-recap
meeting-summary
standup-update
time-breakdown
video-export
db.sqlite
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
pipe.md, Editor Group 1
#!/bin/bash • Untitled-1, Editor Group 1
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: [IP_ADDRESS]
SSH: [IP_ADDRESS]
No Problems
0
0
No Ports Forwarded
0
Update is ready, click to restart.
Update is ready, click to restart.
Notifications
Sign In
Sign In
Screen Reader Optimized
Info: Setting up SSH Host [IP_ADDRESS]: Setting up SSH tunnel...
|
Code
|
#!/bin/bash • Untitled-1 — screenpipe [SSH: 100.73 #!/bin/bash • Untitled-1 — screenpipe [SSH: 100.73.206.126]...
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp-zshDOCKER• 881cloud syncauto-destruct piddeepgram keylanguagesmonitorsDEV (-zsh)disabled0not setall languagesO 82APP (-zsh)• *3-zsh• ×4-zsh• 85$0(ahl-zsh886-zsh100% C2O 87Sat 11 Apr 20:26:58-zsh181• *8no monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry is enabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latestchanges here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.3487542INFOscreenpipe: starting UIevent capture2026-04-11T20:26:05.353656Z2026-04-11T20:26:05.358540ZWARN screenpipe: pi agent install failed: bun not found - install from https://bun.shINFO screenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.363864ZINFOscreenpipe_engine::ui_recorder: Starting UI event capture2026-04-11T20:26:05..378325ZINFOscreenpipe_engine::calendar_speaker_id: speaker identification: started(user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui.recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05i.378564ZINFOscreenpipe_engine::hotframe_cache: hot_frame_cache: warmingfrom DB (2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFOscreenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)2026-04-11T20:26:05.384798ZINFOscreenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe on port 30302026-04-11T20:26:05.528107ZINFO2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting vision recordingfor monitor 1 (1440x900)screenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFOscreenpipe_engine::vision_manager: :manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed list2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900,2026-04-11T20:26:07.067446ZINFOscreenpipe_engine::event_driven_capture: startup capture for monitor 1:2026-04-11T20:26:08..752985ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=visual_change)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: local retention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFO2026-04-11T20:26:55.992688ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:26:57.331771ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)manter 1 Cons...
|
NULL
|
NULL
|
NULL
|
|
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update, 1 requires restart
3
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
SCREENPIPE [SSH: [IP_ADDRESS]]
#recycle
app
consumers
static
.env
cli.py
db.py
docker-compose.yml
Dockerfile
main.py
requirements.txt
data
pipes
ai-habits
pipe.md
day-recap
meeting-summary
standup-update
time-breakdown
video-export
db.sqlite
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
pipe.md, Editor Group 1
#!/bin/bash • Untitled-1, Editor Group 1
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
Claude Code, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: [IP_ADDRESS]
SSH: [IP_ADDRESS]
No Problems
0
0
No Ports Forwarded
0
Update is ready, click to restart.
Update is ready, click to restart.
Notifications
Sign In
Sign In
Screen Reader Optimized
Info: Setting up SSH Host [IP_ADDRESS]: Setting up SSH tunnel
Untitled
Session history
New session
Tired of repeating yourself? Tell Claude to remember what you’ve told it using CLAUDE.md.
Prefer the Terminal experience?
Switch back in Settings.
Switch back in Settings.
Close banner
⌘ Esc to focus or unfocus Claude
⌘ Esc to focus or unfocus Claude
Add
Show command menu (/)
Untitled-1
Untitled-1
Edit automatically
Edit automatically...
|
Code
|
Claude Code — screenpipe [SSH: 100.73.206.126]
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(ahlA100%-zshDOCKER• 881cloud syncauto-destruct piddeepgram keylanguagesmonitorsDEV (-zsh)disabled0O 82not setall languagesno monitors availableAPP (-zsh)• *3-zsh• ×4-zsh• 85-zsh886-zshO 87Sat 11 Apr 20:27:01-zshT81• *8audio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry is enabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latestchanges here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.3487542INFOscreenpipe: starting UIevent capture2026-04-11T20:26:05.353656Z2026-04-11T20:26:05.358540ZWARN screenpipe: pi agent install failed: bun not found - install from https://bun.shINFO screenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.363864ZINFOscreenpipe_engine::ui_recorder: Starting UI event capture2026-04-11T20:26:05..378325ZINFOscreenpipe_engine::calendar_speaker_id: speaker identification: started(user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui.recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05i.378564ZINFOscreenpipe_engine::hotframe_cache: hot_frame_cache: warmingfrom DB (2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFOscreenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)2026-04-11T20:26:05.384798ZINFOscreenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe on port 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache:warmed with 8832026-04-11T20:26:05.683177ZINFOframe entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting vision recordingfor monitor 1 (1440x900)screenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFOscreenpipe_engine::vision_manager: :manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed list2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900,2026-04-11T20:26:07.067446ZINFOscreenpipe_engine::event_driven_capture: startup capture for monitor 1:2026-04-11T20:26:08..752985ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=visual_change)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: local retention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFO2026-04-11T20:26:55.992688ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:26:57.331771ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)manter 1 Cons...
|
NULL
|
NULL
|
NULL
|
|
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update, 1 requires restart
3
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
SCREENPIPE [SSH: [IP_ADDRESS]]
#recycle
app
consumers
static
.env
cli.py
db.py
docker-compose.yml
Dockerfile
main.py
requirements.txt
data
pipes
ai-habits
pipe.md
day-recap
meeting-summary
standup-update
time-breakdown
video-export
db.sqlite
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
pipe.md, Editor Group 1
#!/bin/bash • Untitled-1, Editor Group 1
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
Claude Code, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: [IP_ADDRESS]
SSH: [IP_ADDRESS]
No Problems
0
0
No Ports Forwarded
0
Update is ready, click to restart.
Update is ready, click to restart.
Notifications
Sign In
Sign In
Screen Reader Optimized
Info: Setting up SSH Host [IP_ADDRESS]: Setting up SSH tunnel
Untitled
Session history
New session
Tired of repeating yourself? Tell Claude to remember what you’ve told it using CLAUDE.md.
Prefer the Terminal experience?
Switch back in Settings.
Switch back in Settings.
Close banner
⌘ Esc to focus or unfocus Claude
⌘ Esc to focus or unfocus Claude
Add
Show command menu (/)
Untitled-1
Untitled-1
Edit automatically
Edit automatically...
|
Code
|
Claude Code — screenpipe [SSH: 100.73.206.126]
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp-zshDOCKER• 881cloud syncauto-destruct piddeepgram keylanguagesDEV (-zsh)disabled0not setO 82APP (-zsh)• *3-zsh• x4|-zsh• 85$0(ahl-zsh886-zsh100%O 87Sat 11 Apr 20:27:04-zsh181• *8all languagesmonitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry is enabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latestchanges here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes: pipe scheduler started (generation 2)2026-04-11T20:26:05.3487542INFOscreenpipe: starting UIevent capture2026-04-11T20:26:05.353656Z2026-04-11T20:26:05.358540ZWARN screenpipe: pi agent install failed: bun not found - install from https://bun.shINFO screenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.363864ZINFOscreenpipe_engine::ui_recorder: Starting UI event capture2026-04-11T20:26:05..378325ZINFOscreenpipe_engine::calendar_speaker_id: speaker identification: started(user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui.recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05i.378564ZINFOscreenpipe_engine::hotframe_cache: hot_frame_cache: warmingfrom DB (2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFOscreenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)2026-04-11T20:26:05.384798ZINFOscreenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe on port 30302026-04-11T20:26:05.528107ZINFO2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting vision recordingfor monitor 1 (1440x900)screenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFOscreenpipe_engine::vision_manager: :manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed list2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900,2026-04-11T20:26:07.067446ZINFOscreenpipe_engine::event_driven_capture: startup capture for monitor 1:2026-04-11T20:26:08..752985ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=visual_change)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: local retention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFO2026-04-11T20:26:55.992688ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)screenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:26:57.331771ZINFOscreenpipe_engine:: event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)manter 1 Cons...
|
NULL
|
NULL
|
NULL
|
|
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update, 1 requires restart
3
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
SCREENPIPE [SSH: [IP_ADDRESS]]
#recycle
app
consumers
static
.env
cli.py
db.py
docker-compose.yml
Dockerfile
main.py
requirements.txt
data
pipes
ai-habits
pipe.md
day-recap
meeting-summary
standup-update
time-breakdown
video-export
db.sqlite
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
pipe.md, Editor Group 1
#!/bin/bash • Untitled-1, Editor Group 1
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
Claude Code, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: [IP_ADDRESS]
SSH: [IP_ADDRESS]
No Problems
0
0
No Ports Forwarded
0
Update is ready, click to restart.
Update is ready, click to restart.
Notifications
Sign In
Sign In
Screen Reader Optimized
Info: Setting up SSH Host [IP_ADDRESS]: Setting up SSH tunnel
Untitled
Session history
New session
Tired of repeating yourself? Tell Claude to remember what you’ve told it using CLAUDE.md.
Prefer the Terminal experience?
Switch back in Settings.
Switch back in Settings.
Close banner
⌘ Esc to focus or unfocus Claude
⌘ Esc to focus or unfocus Claude
Add
Show command menu (/)
Untitled-1
Untitled-1
Edit automatically
Edit automatically...
|
Code
|
Claude Code — screenpipe [SSH: 100.73.206.126]
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(ahlA100% <7-zshDOCKER• 881auto-destruct piddeepgram keylanguagesDEV (-zsh)0not setO 82APP (-zsh)• *3-zsh• ×4-zsh• 285-zsh886-zshO 87Sat 11 Apr 20:27:07-zshT81• *8+all languagesmonitorsno monitors availableaudio devicesdisabledyouareusing local processing. all your data stays on your computer.warning: telemetry isenabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.checklatest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes: pipe scheduler started (generation 2)2026-04-11T20:26:05.348754ZINFO screenpipe: starting UIevent capture2026-04-11T20:26:05.35365622026-04-11T20:26:05.358540ZWARN screenpipe: pi agent install failed: bun not found - install from https://bun.shinstali faitedi t n onounar -2026-04-11T20:26:05.363864ZINFO screenpipe_engine::power::manager: initial power profile: Performance Con_ac=true, battery=Some(100))INFO screenpipe_engine::ui_recorder: Starting UI event capture2026-04-11T20:26:05.3783252INFOscreenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warming from DB (2026-04-1017:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFOscreenpipe_engine::meeting_detector: meeting v2: detection loop started (base_interval=5s, profiles=12)2026-04-11T20:26:05.384798ZINFOscreenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect: :mdns: mdns: advertising screenpipe on port 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883 frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.6831772INFOscreenpipe_engine::vision_manager::manager: Starting vision recording for monitor 1 1440x900)2026-04-11T20:26:05.683293ZINFO2026-04-11T20:26:05.683303ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)Tcorting fot onterier, ene re: 202860-10 1-2350. 75- 1screenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed list2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager:2026-04-11T20:26:07.067446ZINFOpersistent SCK stream started for display 1 (1440x900,Zfps)screenpipe_engine::event_driven_capture: startup2026-04-11T20:26:08.752985Zcapture for monitor 1: frame_id=1407, dur=537msINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=visual_change)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe:localretention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFO2026-04-11T20:26:55.992688ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)2026-04-11T20:26:57.331771Zscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)INFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:27:05.408691ZINFO screenpipe_engine::snapshot_compaction: snapshot compaction: found 61 eligible frames...
|
NULL
|
NULL
|
NULL
|
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Irán – Denník N
Irán – Denník N
Vimium Options
Vimium Options
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Search results for "bitwarden" – Add-ons for Firefox (en-US)
Search results for "bitwarden" – Add-ons for Firefox (en-US)
New Tab
New Tab
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Browser Extension Getting Started | Bitwarden
Browser Extension Getting Started | Bitwarden
Extensions – Add-ons for Firefox (en-US)
Extensions – Add-ons for Firefox (en-US)
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
11
/
04
/
2026
Calendar
TOTAL SPAN
1.0h
14:52 → 15:54
ACTIVE
1.0h
BREAKS
0 breaks · 0.0h
SESSIONS
1
62m
FRAMES
612
APPS
6
UI EVENTS
1344
AUDIO
0
ACTIVE PERIOD
14:52 → 15:54
TIME PER APP
— CLICK TO FILTER RIGHT PANEL
iTerm2
5.2m
Firefox
1.5m
Finder
0.6m
QuickTime Player
0.5m
NetAuthAgent
0.1m
Raycast
0.1m
Websites
Windows
UI Events
nas.lakylak.xyz/desktop/#/
0.7m
play.hbomax.com/video/watch/6b742798-e5fa-4f90-8beb-74c328dc5028/65d19c63-e85e-4392-8594-f0f2e0a1dc2d
0.1m
nas.lakylak.xyz/desktop/#/login/account
0.1m
login.tailscale.com/login?next_url=%2Fadmin
0.1m
dennikn.sk/5263377/lod-orion-uspesne-pristala-na-zemi-desat-veci-ktore-si-pamatat-na-misii-artemis-ii/
0.1m
http://localhost:3030
0m
addons.mozilla.org/en-US/firefox/addon/vimium-ff/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0m
accounts.google.com/v3/signin/accountchooser?access_type=offline&client_id=674241127656-lmq9su4p8ni1tcpuh6eqidoornqtvmvi.apps.googleusercontent.com&prompt=select_account&redirect_uri=https%3A%2F%2Flogin.tailscale.com%2Fa%2Foauth_response&response_type=code&scope=openid+email+profile&state=tc-ftYwP8oB0urJfQZeh42KPfA&dsh=S1949714251%3A1775911302074699&o2v=2&service=lso&flowName=GeneralOAuthFlow&opparams=%253F&continue=https%3A%2F%2Faccounts.google.com%2Fsignin%2Foauth%2Fconsent%3Fauthuser%3Dunknown%26part%3DAJi8hAOOoeMJ9h1ZWE-Aau2rWQdjwJ-4Enpv6Ci-0hiDSq5jW9TsVTl1btOELm96_EZaQdgfRwBdj1zZGB_CYauRC0fkTqY_cZ35H_NcJOU2_4Ax0Gtto-fKf-nDgh4daUIBqdTh68bjSxOce25-KnK0XYdHV8mzb69bNhDZHVDj_gb42yLS6CaLOtRfvBqDUDqR3SzLMQPfBkXHhJz6IM_7wq52TLTL563ihzeGQBECsxCnD1Yk27REW5r_eZ0TNXkkAX7P1hB8gAkBKuZVXHltsgP7jvfc8R1fsuXURwjdV8kBOMOg3Reld6-0t5nB9qwgvuYCJsuo0Q7IMz9o-t41651a_Wsc0FnlTxFC_0DA-eKXtSlPZHRy9BW_O_UgliMh8Y9cnLpKZ4r9A_LwCm6flXHR1tZWe_NA_YGhQ9EYSdByTuW1hMcIXXh1Alssc0Sb9BtxZ5mPnlLjTXaWd8LEtCrsHv1HQQ%26flowName%3DGeneralOAuthFlow%26as%3DS1949714251%253A1775911302074699%26client_id%3D674241127656-lmq9su4p8ni1tcpuh6eqidoornqtvmvi.apps.googleusercontent.com%26requestPath%3D%252Fsignin%252Foauth%252Fconsent%23&app_domain=https%3A%2F%2Flogin.tailscale.com
0m...
|
Firefox
|
Screenpipe Dashboard — Personal
|
http://100.73.206.126:8766
|
|
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update, 1 requires restart
3
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
SCREENPIPE [SSH: [IP_ADDRESS]]
#recycle
app
consumers
static
.env
cli.py
db.py
docker-compose.yml
Dockerfile
main.py
requirements.txt
data
pipes
ai-habits
pipe.md
day-recap
meeting-summary
standup-update
time-breakdown
video-export
db.sqlite
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
pipe.md, Editor Group 1
#!/bin/bash • Untitled-1, Editor Group 1
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
Build screenpipe data UI…, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: [IP_ADDRESS]
SSH: [IP_ADDRESS]
No Problems
0
0
No Ports Forwarded
0
Update is ready, click to restart.
Update is ready, click to restart.
Notifications
Sign In
Sign In
Screen Reader Optimized
Info: Setting up SSH Host [IP_ADDRESS]: Setting up SSH tunnel
Build screenpipe data UI and summary app
Session history
New session
Message actions
lets build app around screenpipe data and db. THe idea is to have ui and data consumers. So I can run regular commands at the end ot the day (or on demand) and create soem summary.
Thinking
Thinking
Let me explore the screenpipe directory to understand what we're working with.
Bash
List screenpipe directory contents
IN
ls /volume1/screenpipe/
Copy code to clipboard
OUT
data
db.sqlite
pipes
#recycle
[rerun: b1]
Bash
List data and pipes directories
IN
ls /volume1/screenpipe/data/ | head -20 && ls /volume1/screenpipe/pipes/
Copy code to clipboard
OUT
2026-04-09
2026-04-11
ai-habits
day-recap
meeting-summary
standup-update
time-breakdown
video-export
[rerun: b2]
Bash
List tables in screenpipe SQLite database
IN
sqlite3 /volume1/screenpipe/db.sqlite ".tables"
Copy code to clipboard
OUT
_sqlx_migrations meetings
audio_chunks memories
audio_tags memories_fts
audio_transcriptions memories_fts_config
audio_transcriptions_fts memories_fts_data
audio_transcriptions_fts_config memories_fts_docsize
audio_transcriptions_fts_data memories_fts_idx
audio_transcriptions_fts_docsize ocr_text
audio_transcriptions_fts_idx pipe_executions
elements pipe_scheduler_state
elements_fts speaker_embeddings
elements_fts_config speakers
elements_fts_data tags
elements_fts_docsize ui_events
elements_fts_idx ui_events_fts
frames ui_events_fts_config
frames_fts ui_events_fts_data
frames_fts_config ui_events_fts_docsize
frames_fts_content ui_events_fts_idx
frames_fts_data video_chunks
frames_fts_docsize vision_tags
frames_fts_idx
[rerun: b3]
Bash
Get ocr_text table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(ocr_text);"
Copy code to clipboard
OUT
0|frame_id|INTEGER|1||0
1|text|TEXT|1||0
2|text_json|TEXT|0||0
3|app_name|TEXT|1|''|0
4|ocr_engine|TEXT|1|'unknown'|0
5|window_name|TEXT|0||0
6|focused|BOOLEAN|0|FALSE|0
7|text_length|INTEGER|0||0
8|sync_id|TEXT|0||0
9|synced_at|DATETIME|0||0
[rerun: b4]
Bash
Get audio_transcriptions table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(audio_transcriptions);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|audio_chunk_id|INTEGER|1||0
2|offset_index|INTEGER|1||0
3|timestamp|TIMESTAMP|1||0
4|transcription|TEXT|1||0
5|device|TEXT|1|''|0
6|is_input_device|BOOLEAN|1|TRUE|0
7|speaker_id|INTEGER|0||0
8|transcription_engine|TEXT|1|'Whisper'|0
9|start_time|REAL|0||0
10|end_time|REAL|0||0
11|text_length|INTEGER|0||0
12|sync_id|TEXT|0||0
13|synced_at|DATETIME|0||0
[rerun: b5]
Bash
Get frames, ui_events, video_chunks schemas
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(frames); PRAGMA table_info(ui_events); PRAGMA table_info(video_chunks);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|video_chunk_id|INTEGER|0|NULL|0
2|offset_index|INTEGER|1|0|0
3|timestamp|TIMESTAMP|1||0
4|name|TEXT|0||0
5|app_name|TEXT|0|NULL|0
6|window_name|TEXT|0|NULL|0
7|focused|BOOLEAN|0|NULL|0
8|browser_url|TEXT|0|NULL|0
9|device_name|TEXT|1|''|0
10|sync_id|TEXT|0||0
11|machine_id|TEXT|0||0
12|synced_at|DATETIME|0||0
13|snapshot_path|TEXT|0|NULL|0
14|accessibility_text|TEXT|0|NULL|0
15|accessibility_tree_json|TEXT|0|NULL|0
16|content_hash|INTEGER|0|NULL|0
17|simhash|INTEGER|0|NULL|0
18|capture_trigger|TEXT|0|NULL|0
19|text_source|TEXT|0|NULL|0
20|cloud_blob_id|TEXT|0|NULL|0
21|full_text|TEXT|0|NULL|0
22|elements_ref_frame_id|INTEGER|0|NULL|0
0|id|INTEGER|0||1
1|timestamp|DATETIME|1|CURRENT_TIMESTAMP|0
2|session_id|TEXT|0||0
3|relative_ms|INTEGER|1|0|0
4|event_type|TEXT|1||0
5|x|INTEGER|0||0
6|y|INTEGER|0||0
7|delta_x|INTEGER|0||0
8|delta_y|INTEGER|0||0
9|button|INTEGER|0||0
10|click_count|INTEGER|0||0
11|key_code|INTEGER|0||0
12|modifiers|INTEGER|0||0
13|text_content|TEXT|0||0
14|text_length|INTEGER|0||0
15|app_name|TEXT|0||0
16|app_pid|INTEGER|0||0
17|window_title|TEXT|0||0
18|browser_url|TEXT|0||0
19|element_role|TEXT|0||0
20|element_name|TEXT|0||0
21|element_value|TEXT|0||0
22|element_description|TEXT|0||0
23|element_automation_id|TEXT|0||0
24|element_bounds|TEXT|0||0
25|frame_id|INTEGER|0||0
26|sync_id|TEXT|0||0
27|machine_id|TEXT|0||0
28|synced_at|DATETIME|0||0
0|id|INTEGER|0||1
1|file_path|TEXT|1||0
2|device_name|TEXT|1|''|0
3|sync_id|TEXT|0||0
4|machine_id|TEXT|0||0
5|synced_at|DATETIME|0||0
6|fps|REAL|1|0.5|0
7|cloud_blob_id|TEXT|0|NULL|0
[rerun: b6]
Bash
Check data counts and date ranges
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM frames;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM audio_transcriptions;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*) FROM ocr_text;" 2>/dev/null
Copy code to clipboard
OUT
1135|2026-04-09T16:53:09.043761+00:00|2026-04-11T12:54:42.597794+00:00
3|2026-04-09T16:53:20+00:00|2026-04-09T17:02:52+00:00
666
[rerun: b7]
Bash
Explore existing pipes for patterns
IN
ls /volume1/screenpipe/pipes/day-recap/ 2>/dev/null && cat /volume1/screenpipe/pipes/day-recap/*.js 2>/dev/null | head -50
Copy code to clipboard
OUT
pipe.md
[rerun: b8]
Bash
Read day-recap pipe documentation
IN
cat /volume1/screenpipe/pipes/day-recap/pipe.md
Copy code to clipboard
OUT
---
schedule: manual
enabled: true
template: true
title: Day Recap
description: "Today's accomplishments, key moments, and unfinished work"
icon: "📋"
featured: true
---
Analyze my screen and audio recordings from today (last 16 hours only).
Read screenpipe skill first.
Use this exact format:
## Summary
One sentence: what I mainly did today.
## Accomplishments
- Top 3 things I finished, with timestamps (e.g. "2:30 PM")
- Name specific apps, files, or projects
## Key Moments
- Important things I saw, said, or heard — with timestamps
## Unfinished Work
- What I should continue tomorrow — name the app/file/task
## Patterns
- Apps I used most, topics that came up repeatedly
Only report what you can verify from the data. End with: "**Next step:** [most important thing to continue]"
[rerun: b9]
Bash
Sample app names from frames
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT DISTINCT app_name FROM frames WHERE app_name != '' LIMIT 20;"
Copy code to clipboard
OUT
Safari
Activity Monitor
Dia
iTerm2
Control Centre
UserNotificationCenter
Finder
Claude
Slack
Firefox
Raycast
NetAuthAgent
QuickTime Player
[rerun: b10]
Bash
Sample joined frame+ocr data for today
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT f.timestamp, o.app_name, o.window_name, substr(o.text, 1, 100) as text FROM frames f JOIN ocr_text o ON f.id = o.frame_id WHERE DATE(f.timestamp) = '2026-04-11' LIMIT 5;"
Copy code to clipboard
OUT
2026-04-11T11:53:00.627698+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <47H5Sat 11 Apr 14:53:00-zshDOCKE
2026-04-11T11:53:02.005967+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <7H5Sat 11 Apr 14:53:01-zshDOCKER
2026-04-11T11:53:03.627468+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:03-zshDOCKERuse p
2026-04-11T11:53:05.528794+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:05-zshDOCKERuse p
2026-04-11T11:53:07.662098+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <7Sat 11 Apr 14:53:07-zshDOCKERuse pi
[rerun: b11]
Bash
Sample recent audio transcriptions
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT timestamp, substr(transcription,1,100) as text, device FROM audio_transcriptions ORDER BY timestamp DESC LIMIT 5;"
Copy code to clipboard
OUT
2026-04-09T17:02:52+00:00|.|System Audio
2026-04-09T16:59:22+00:00|Class is technically...|System Audio
2026-04-09T16:53:20+00:00|I do for you. Run the credit check. Deal apartment. Okay.|System Audio
[rerun: b12]
Thinking
Thinking
Good data to work with. Here's what we have:
frames
+
ocr_text
: Screen captures with OCR text, app name, window name (1135 frames so far)
audio_transcriptions
: Voice/system audio transcripts
ui_events
: Mouse/keyboard events with app context
video_chunks
: Raw video files
Before I start building, a few quick questions:
Tech stack
— Python OK? (FastAPI for the web UI backend, Click for CLI commands, HTMX for the frontend to keep it simple)
AI summaries
— Do you have a Claude API key to use for generating the actual summaries? Or should I integrate with a local model / skip AI for now?
What summaries matter most?
Day recap (what apps/windows you used, key text seen)
App time breakdown (time per app)
Audio/conversation recap
Custom searchable timeline
Here's the architecture I'm thinking:
Copy code to clipboard
/volume1/screenpipe/app/
├── main.py # FastAPI web UI
├── cli.py # Click CLI: `python cli.py day-recap`
├── db.py # Read-only queries against db.sqlite
├── consumers/
│ ├── activity.py # App usage, time per window
│ ├── ocr.py # OCR text aggregation + search
│ ├── audio.py # Transcription queries
│ └── summary.py # AI summary builder
└── static/
└── index.html # Single-page UI
CLI commands would look like:
Copy code to clipboard
python cli.py day-recap # EOD summary
python cli.py activity --date today # App time breakdown
python cli.py search "docker" # Search OCR/audio text
python cli.py serve # Launch web UI
Does this direction work? Any preferences on the stack or which summaries to prioritize?
Message actions
seesm ok
Thinking
Thinking
Bash
Check Python and available packages
IN
python3 --version && pip3 list 2>/dev/null | grep -E "fastapi|uvicorn|click|anthropic|httpx|jinja"
Copy code to clipboard
OUT
Python 3.11.2
[rerun: b1]
Bash
Verify join works for today's data
IN
sqlite3 /volume1/screenpipe/db.sqlite "
SELECT f.timestamp, o.app_name, o.window_name, length(o.text) as txt_len
FROM frames f JOIN ocr_text o ON f.id = o.frame_id
WHERE DATE(f.timestamp) = '2026-04-11'
ORDER BY f.timestamp DESC LIMIT 3;
"
Copy code to clipboard
OUT
2026-04-11T12:54:42.597794+00:00|||2111
2026-04-11T12:54:41.915916+00:00|||2110
2026-04-11T12:54:39.912712+00:00|||2111
[rerun: b2]
Bash
Install required packages
IN
pip3 install fastapi uvicorn click anthropic python-dotenv 2>&1 | tail -5
Copy code to clipboard
OUT
/bin/bash: line 1: pip3: command not found
[rerun: b3]
Bash
Find pip
IN
which pip || which pip3 || python3 -m pip --version 2>/dev/null
Copy code to clipboard
OUT
Exit code 1
[rerun: b4]
Bash
Bootstrap pip then install packages
IN
python3 -m ensurepip --upgrade 2>&1 && python3 -m pip install fastapi uvicorn click anthropic python-dotenv 2>&1 | tail -10
Copy code to clipboard
OUT
Exit code 1
/usr/bin/python3: No module named ensurepip
[rerun: b5]
Bash
Install pip via apt
IN
apt-get install -y python3-pip python3-venv 2>&1 | tail -5
Copy code to clipboard
OUT
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
[rerun: b6]
Bash
Install pip with sudo
Reason:
lets make it in docker, not to install it in nas directly
IN
sudo apt-get install -y python3-pip python3-venv 2>&1 | tail -5
Copy code to clipboard
Good call. Let me check what Docker setup you already have and build a proper containerized app.
Bash
Check existing docker-compose for reference
IN
ls /volume2/docker/paperlessngx/ && cat /volume2/docker/paperlessngx/docker-compose.yml 2>/dev/null | head -30
Copy code to clipboard
OUT
consume
data
db
docker-compose.yml
export
mcp-server
media
redis
trash
services:
redis:
image: redis:8
command:
- /bin/sh
- -c
- redis-server --requirepass redispass
container_name: PaperlessNGX-REDIS
hostname: paper-redis
security_opt:
- no-new-privileges:true
read_only: true
user: 1000:10
healthcheck:
test: ["CMD-SHELL", "redis-cli ping || exit 1"]
volumes:
- /volume2/docker/paperlessngx/redis:/data:rw
environment:
TZ: Europe/Sofia
restart: always
db:
image: postgres:17
container_name: PaperlessNGX-DB
hostname: paper-db
mem_limit: 1g
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "pg_isready", "-q", "-d", "paperless", "-U", "paperlessuser"]
[rerun: b7]
Bash
Check Docker availability
IN
docker --version && docker compose version 2>/dev/null
Copy code to clipboard
OUT
Docker version 26.1.0, build 9714adc
Docker Compose version v2.26.1
[rerun: b8]
Bash
Create app directory structure
IN
mkdir -p /volume1/screenpipe/app/consumers /volume1/screenpipe/app/static
Copy code to clipboard
OUT
[rerun: b9]
Now let me build everything. I'll create all the files:
Write
requirements.txt
requirements.txt
6 lines
fastapi==0.115.12
uvicorn[standard]==0.34.0
click==8.1.8
anthropic==0.49.0
python-dotenv==1.1.0
Write
Dockerfile
Dockerfile
13 lines
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "[IP_ADDRESS]", "--port", "8000"]
Write
db.py
db.py
28 lines
import sqlite3
from contextlib import contextmanager
from datetime import date, datetime, timedelta, timezone
from typing import Generator
DB_PATH = "/data/db.sqlite"
@contextmanager
def get_conn() -> Generator[sqlite3.Connection, None, None]:
conn = sqlite3.connect(f"file:{DB_PATH}?mode=ro", uri=True)
conn.row_factory = sqlite3.Row
try:
yield conn
finally:
conn.close()
def date_range(for_date: date) -> tuple[str, str]:
"""Return ISO timestamps for start/end of a given date (UTC)."""
start = datetime(for_date.year, for_date.month, for_date.day, tzinfo=timezone.utc)
end = start + timedelta(days=1)
return start.isoformat(), end.isoformat()
def today() -> date:
return datetime.now(timezone.utc).date()
Write
__init__.py
__init__.py
1 line
Write
activity.py
activity.py
123 lines
"""App usage and window focus time consumer."""
from datetime import date
from typing import Any
from db import get_conn, date_range, today as _today
def app_time(for_date: date | None = None) -> list[dict[str, Any]]:
"""Return minutes spent per app for a given date, sorted descending."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT
o.app_name,
COUNT(*) as frame_count,
-- each frame ~ 2s at 0.5fps; convert to minutes
ROUND(COUNT(*) * 2.0 / 60, 1) as minutes
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
GROUP BY o.app_name
ORDER BY frame_count DESC
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
def window_time(for_date: date | None = None, app: str | None = None) -> list[dict[str, Any]]:
"""Return minutes spent per window/tab, optionally filtered by app."""
d = for_date or _today()
start, end = date_range(d)
query = """
SELECT
o.app_name,
o.window_name,
COUNT(*) as frame_count,
ROUND(COUNT(*) * 2.0 / 60, 1) as minutes
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
"""
params: list = [start, end]
if app:
query += " AND o.app_name = ?"
params.append(app)
query += " GROUP BY o.app_name, o.window_name ORDER BY frame_count DESC LIMIT 50"
with get_conn() as conn:
rows = conn.execute(query, params).fetchall()
return [dict(r) for r in rows]
def timeline(for_date: date | None = None, interval_minutes: int = 15) -> list[dict[str, Any]]:
"""Return activity bucketed into N-minute intervals."""
d = for_date or _today()
start, end = date_range(d)
interval_sec = interval_minutes * 60
with get_conn() as conn:
rows = conn.execute(
f"""
SELECT
datetime(
(strftime('%s', f.timestamp) / {interval_sec}) * {interval_sec},
'unixepoch'
) as bucket,
o.app_name,
COUNT(*) as frames
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
GROUP BY bucket, o.app_name
ORDER BY bucket, frames DESC
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
def summary_stats(for_date: date | None = None) -> dict[str, Any]:
"""Return high-level stats for a date."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
frames_row = conn.execute(
"SELECT COUNT(*) as n, MIN(timestamp) as first, MAX(timestamp) as last "
"FROM frames WHERE timestamp >= ? AND timestamp < ?",
(start, end),
).fetchone()
app_count = conn.execute(
"""
SELECT COUNT(DISTINCT o.app_name) as n
FROM frames f JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ? AND o.app_name != ''
""",
(start, end),
).fetchone()
audio_count = conn.execute(
"SELECT COUNT(*) as n FROM audio_transcriptions "
"WHERE timestamp >= ? AND timestamp < ?",
(start, end),
).fetchone()
return {
"date": str(d),
"total_frames": frames_row["n"],
"first_seen": frames_row["first"],
"last_seen": frames_row["last"],
"unique_apps": app_count["n"],
"audio_segments": audio_count["n"],
}
Write
ocr.py
ocr.py
92 lines
"""OCR text search and aggregation consumer."""
from datetime import date
from typing import Any
from db import get_conn, date_range, today as _today
def search(query: str, for_date: date | None = None, limit: int = 50) -> list[dict[str, Any]]:
"""Full-text search OCR content."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT
f.timestamp,
o.app_name,
o.window_name,
snippet(ocr_text_fts, 0, '[', ']', '...', 20) as snippet
FROM ocr_text_fts
JOIN ocr_text o ON ocr_text_fts.rowid = o.rowid
JOIN frames f ON o.frame_id = f.id
WHERE ocr_text_fts MATCH ?
AND f.timestamp >= ? AND f.timestamp < ?
ORDER BY rank
LIMIT ?
""",
(query, start, end, limit),
).fetchall()
return [dict(r) for r in rows]
def text_for_date(for_date: date | None = None, focused_only: bool = True) -> list[dict[str, Any]]:
"""Return all OCR text for a date, optionally only focused windows."""
d = for_date or _today()
start, end = date_range(d)
query = """
SELECT
f.timestamp,
o.app_name,
o.window_name,
o.text
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
AND length(o.text) > 20
"""
params: list = [start, end]
if focused_only:
query += " AND o.focused = TRUE"
query += " ORDER BY f.timestamp"
with get_conn() as conn:
rows = conn.execute(query, params).fetchall()
return [dict(r) for r in rows]
def deduplicated_text(for_date: date | None = None, chunk_minutes: int = 5) -> list[dict[str, Any]]:
"""
Return OCR text deduplicated by time chunk + app to reduce LLM token usage.
Groups frames into N-minute buckets and returns one representative text per app per bucket.
"""
d = for_date or _today()
start, end = date_range(d)
interval_sec = chunk_minutes * 60
with get_conn() as conn:
rows = conn.execute(
f"""
SELECT
datetime(
(strftime('%s', f.timestamp) / {interval_sec}) * {interval_sec},
'unixepoch'
) as bucket,
o.app_name,
o.window_name,
substr(o.text, 1, 500) as text
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
AND length(o.text) > 20
GROUP BY bucket, o.app_name
ORDER BY bucket
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
Write
audio.py
audio.py
61 lines
"""Audio transcription consumer."""
from datetime import date
from typing import Any
from db import get_conn, date_range, today as _today
def transcriptions(for_date: date | None = None) -> list[dict[str, Any]]:
"""Return all audio transcriptions for a date."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT timestamp, transcription, device, is_input_device, speaker_id
FROM audio_transcriptions
WHERE timestamp >= ? AND timestamp < ?
AND length(transcription) > 2
ORDER BY timestamp
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
def search(query: str, for_date: date | None = None, limit: int = 30) -> list[dict[str, Any]]:
"""Search audio transcriptions."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT
a.timestamp,
a.device,
snippet(audio_transcriptions_fts, 0, '[', ']', '...', 20) as snippet
FROM audio_transcriptions_fts
JOIN audio_transcriptions a ON audio_transcriptions_fts.rowid = a.id
WHERE audio_transcriptions_fts MATCH ?
AND a.timestamp >= ? AND a.timestamp < ?
ORDER BY rank
LIMIT ?
""",
(query, start, end, limit),
).fetchall()
return [dict(r) for r in rows]
def formatted_transcript(for_date: date | None = None) -> str:
"""Return audio as a readable transcript string."""
rows = transcriptions(for_date)
if not rows:
return "(no audio transcriptions)"
lines = []
for r in rows:
label = "MIC" if r["is_input_device"] else "SYS"
lines.append(f"[{r['timestamp']}] [{label}] {r['transcription']}")
return "\n".join(lines)
Write
summary.py
summary.py
162 lines
"""AI summary generator using Claude."""
import os
from datetime import date
from typing import Any
from consumers.activity import app_time, summary_stats
from consumers.ocr import deduplicated_text
from consumers.audio import formatted_transcript
SUMMARY_TYPES = {
"day_recap": {
"title": "Day Recap",
"prompt": """\
You are analyzing a person's computer activity for the day.
## App usage (minutes per app):
{app_time}
## Screen content (sampled every 5 minutes):
{ocr_text}
## Audio/speech:
{audio}
Write a concise day recap using EXACTLY this format:
## Summary
One sentence: what I mainly worked on today.
## Accomplishments
- Top 3 things I finished, with approximate times
- Name specific apps, files, or projects
## Key Moments
- Important things seen or heard, with timestamps
## Unfinished Work
- What to continue tomorrow
## Patterns
- Apps used most, topics that came up repeatedly
Only report what you can verify from the data. End with:
**Next step:** [most important thing to continue]""",
},
"standup": {
"title": "Standup Update",
"prompt": """\
You are analyzing a person's computer activity for the day.
## App usage (minutes per app):
{app_time}
## Screen content (sampled every 5 minutes):
{ocr_text}
## Audio/speech:
{audio}
Write a brief standup update:
**Yesterday:** What I worked on (2-3 bullets)
**Today:** What I plan to continue (1-2 bullets)
**Blockers:** Any issues observed (or "None")
Keep it under 150 words. Only report what's verifiable from the data.""",
},
"focus_time": {
"title": "Focus & Distraction Analysis",
"prompt": """\
You are analyzing a person's computer activity for the day.
## App usage (minutes per app):
{app_time}
## Screen content (sampled every 5 minutes):
{ocr_text}
Analyze focus vs distraction patterns:
## Deep Work Periods
- When and how long were sustained focus sessions?
- What was being worked on?
## Distractions
- Which apps/sites were used recreationally?
- How much time was lost to context switching?
## Recommendations
- 2-3 concrete suggestions to improve focus tomorrow
Be specific with times and app names.""",
},
}
def _build_context(for_date: date) -> dict[str, str]:
apps = app_time(for_date)
app_lines = "\n".join(f"- {a['app_name']}: {a['minutes']} min" for a in apps[:20])
ocr_rows = deduplicated_text(for_date, chunk_minutes=5)
ocr_lines = "\n".join(
f"[{r['bucket']}] {r['app_name']} / {r['window_name'] or ''}: {r['text'][:200]}"
for r in ocr_rows[:100]
)
audio = formatted_transcript(for_date)
return {
"app_time": app_lines or "(no app data)",
"ocr_text": ocr_lines or "(no screen data)",
"audio": audio[:3000] if len(audio) > 3000 else audio,
}
def generate(
summary_type: str = "day_recap",
for_date: date | None = None,
api_key: str | None = None,
) -> dict[str, Any]:
"""Generate an AI summary. Returns dict with 'title', 'content', 'date'."""
import anthropic
d = for_date or date.today()
key = api_key or os.environ.get("ANTHROPIC_API_KEY", "")
if not key:
return {
"title": "Error",
"content": "ANTHROPIC_API_KEY not set. Add it to your .env file.",
"date": str(d),
}
spec = SUMMARY_TYPES.get(summary_type)
if not spec:
return {"title": "Error", "content": f"Unknown summary type: {summary_type}", "date": str(d)}
stats = summary_stats(d)
if stats["total_frames"] == 0:
return {
"title": spec["title"],
"content": f"No screen data found for {d}.",
"date": str(d),
}
ctx = _build_context(d)
prompt = spec["prompt"].format(**ctx)
client = anthropic.Anthropic(api_key=key)
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
)
return {
"title": spec["title"],
"content": message.content[0].text,
"date": str(d),
"stats": stats,
}
Now the FastAPI backend and CLI:
Write
main.py
main.py
89 lines
"""Screenpipe dashboard — FastAPI web UI."""
import os
from datetime import date, datetime
from typing import Any
from dotenv import load_dotenv
from fastapi import FastAPI, Query
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
load_dotenv()
from consumers.activity import app_time, window_time, timeline, summary_stats
from consumers.ocr import search as ocr_search
from consumers.audio import transcriptions, search as audio_search
from consumers.summary import generate as gen_summary, SUMMARY_TYPES
app = FastAPI(title="Screenpipe Dashboard")
app.mount("/static", StaticFiles(directory="static"), name="static")
def _parse_date(d: str | None) -> date | None:
if not d:
return None
try:
return date.fromisoformat(d)
except ValueError:
return None
@app.get("/", response_class=HTMLResponse)
async def index():
with open("static/index.html") as f:
return f.read()
# ── Activity ──────────────────────────────────────────────────────────────────
@app.get("/api/stats")
async def stats(d: str | None = Query(None)):
return summary_stats(_parse_date(d))
@app.get("/api/activity/apps")
async def activity_apps(d: str | None = Query(None)):
return app_time(_parse_date(d))
@app.get("/api/activity/windows")
async def activity_windows(d: str | None = Query(None), app_name: str | None = Query(None)):
return window_time(_parse_date(d), app_name)
@app.get("/api/activity/timeline")
async def activity_timeline(d: str | None = Query(None), interval: int = Query(15)):
return timeline(_parse_date(d), interval)
# ── Search ───────────────────────────────────────────────────────────────────
@app.get("/api/search/ocr")
async def search_ocr(q: str, d: str | None = Query(None), limit: int = 50):
return ocr_search(q, _parse_date(d), limit)
@app.get("/api/search/audio")
async def search_audio_endpoint(q: str, d: str | None = Query(None), limit: int = 30):
return audio_search(q, _parse_date(d), limit)
# ── Audio ─────────────────────────────────────────────────────────────────────
@app.get("/api/audio")
async def audio(d: str | None = Query(None)):
return transcriptions(_parse_date(d))
# ── Summaries ─────────────────────────────────────────────────────────────────
@app.get("/api/summary/types")
async def summary_types():
return [{"id": k, "title": v["title"]} for k, v in SUMMARY_TYPES.items()]
@app.post("/api/summary/generate")
async def generate_summary(type: str = "day_recap", d: str | None = None):
result = gen_summary(type, _parse_date(d))
return result
Write
cli.py
cli.py
131 lines
#!/usr/bin/env python3
"""Screenpipe CLI — run summaries and reports on demand."""
import os
import sys
from datetime import date, timedelta
import click
from dotenv import load_dotenv
load_dotenv()
sys.path.insert(0, os.path.dirname(__file__))
from consumers.activity import app_time, window_time, summary_stats
from consumers.ocr import search as ocr_search
from consumers.audio import transcriptions
from consumers.summary import generate as gen_summary, SUMMARY_TYPES
def _resolve_date(d_str: str | None) -> date | None:
if not d_str:
return None
if d_str == "yesterday":
return date.today() - timedelta(days=1)
if d_str == "today":
return date.today()
return date.fromisoformat(d_str)
@click.group()
def cli():
"""Screenpipe data explorer and summariser."""
@cli.command()
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
@click.option("--type", "-t", "summary_type", default="day_recap",
type=click.Choice(list(SUMMARY_TYPES.keys())), show_default=True)
def summary(d, summary_type):
"""Generate an AI summary for a date (default: today)."""
target = _resolve_date(d)
click.echo(f"Generating {SUMMARY_TYPES[summary_type]['title']} for {target or date.today()}...")
result = gen_summary(summary_type, target)
click.echo(f"\n{'─'*60}")
click.echo(f" {result['title']} — {result['date']}")
click.echo(f"{'─'*60}\n")
click.echo(result["content"])
if "stats" in result:
s = result["stats"]
click.echo(f"\n[data: {s['total_frames']} frames, {s['unique_apps']} apps, "
f"{s['audio_segments']} audio segments]")
@cli.command()
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
@click.option("--app", "-a", default=None, help="Filter by app name")
@click.option("--windows", "-w", is_flag=True, help="Show window breakdown instead of apps")
def activity(d, app, windows):
"""Show time spent per app or window."""
target = _resolve_date(d)
label = str(target or date.today())
if windows or app:
rows = window_time(target, app)
click.echo(f"\nWindow time — {label}" + (f" [{app}]" if app else ""))
click.echo(f"{'App':<25} {'Window':<40} {'Min':>6}")
click.echo("─" * 75)
for r in rows:
click.echo(f"{r['app_name']:<25} {(r['window_name'] or '')[:40]:<40} {r['minutes']:>6}")
else:
rows = app_time(target)
stats = summary_stats(target)
click.echo(f"\nApp time — {label}")
click.echo(f"{'App':<30} {'Minutes':>8}")
click.echo("─" * 40)
for r in rows:
click.echo(f"{r['app_name']:<30} {r['minutes']:>8}")
click.echo(f"\nTotal frames: {stats['total_frames']} | "
f"Active: {stats['first_seen']} → {stats['last_seen']}")
@cli.command()
@click.argument("query")
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
@click.option("--audio", is_flag=True, help="Search audio instead of screen text")
@click.option("--limit", "-n", default=20, show_default=True)
def search(query, d, audio, limit):
"""Search OCR screen text or audio transcriptions."""
from consumers.audio import search as audio_search_fn
target = _resolve_date(d)
if audio:
rows = audio_search_fn(query, target, limit)
click.echo(f"\nAudio results for '{query}':")
for r in rows:
click.echo(f" [{r['timestamp']}] {r['snippet']}")
else:
rows = ocr_search(query, target, limit)
click.echo(f"\nOCR results for '{query}':")
for r in rows:
click.echo(f" [{r['timestamp']}] {r['app_name']} / {r['window_name'] or ''}")
click.echo(f" {r['snippet']}")
@cli.command()
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
def audio(d):
"""Show audio transcriptions for a date."""
target = _resolve_date(d)
rows = transcriptions(target)
if not rows:
click.echo("No audio transcriptions found.")
return
click.echo(f"\nAudio transcriptions — {target or date.today()}")
click.echo("─" * 60)
for r in rows:
label = "MIC" if r["is_input_device"] else "SYS"
click.echo(f"[{r['timestamp']}] [{label}] {r['transcription']}")
@cli.command()
def serve():
"""Start the web UI (runs uvicorn on port 8000)."""
import uvicorn
click.echo("Starting Screenpipe dashboard at http://localhost:8000")
uvicorn.run("main:app", host="[IP_ADDRESS]", port=8000, reload=False)
if __name__ == "__main__":
cli()
Now the frontend:
Write...
|
Code
|
Build screenpipe data UI… — screenpipe [SSH: 100.7 Build screenpipe data UI… — screenpipe [SSH: 100.73.206.126]...
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(ahl-zshDOCKERdeepgram keylanguages• 881DEV (-zsh)not setall languagesО ₴2APP (-zsh)• *3-zsh• x4|-zsh• 285-zsh886-zsh100% <7O 87Sat 11 Apr 20:27:19-zsh181• *8monitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry isenabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.3487547ZINFO screenpipe: starting UI event capture2026-04-11T20:26:05.353656ZWARNscreenpipe: pi agent install failed: bun not found - install from https://bun.sh2026-04-11T20:26:05.358540ZINFO2026-04-11T20:26:05.363864Zscreenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.378325ZINFO screenpipe_engine::ui_recorder: Starting UI event captureINFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB(2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFO2026-04-11T20:26:051.384798ZINFOscreenpipe_engine::meeting_detector: meeting V2: detection loop started (base_interval=5s, profiles=12)screenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe onport 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting visionrecordingfor monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFO2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed listscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)2026-04-11T20:26:07.067446ZINFO2026-04-11T20:26:08.752985ZINFOscreenpipe-engine::eventdriven.capture: Sonteut dedup: skipping copture for monitoo 1 (hrs -9215443531147982392, triggeravisualchange)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: localretention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)2026-04-11T20:26:55.992688ZINFO2026-04-11T20:26:57.331771ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:27:05408691ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)screenpipe_engine::snapshot_compaction: snapshot compaction: found 61eligible frames2026-04-11T20:27:09.664908ZINFOscreenpipe_engine::snapshot_compaction: snapshot compaction: 61 frames, 9.4MB 3.3MB (2.8x), 61 JPEGs deleted...
|
NULL
|
NULL
|
NULL
|
|
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update, 1 requires restart
3
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
SCREENPIPE [SSH: [IP_ADDRESS]]
#recycle
app
consumers
static
.env
cli.py
db.py
docker-compose.yml
Dockerfile
main.py
requirements.txt
data
pipes
ai-habits
pipe.md
day-recap
meeting-summary
standup-update
time-breakdown
video-export
db.sqlite
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
pipe.md, Editor Group 1
#!/bin/bash • Untitled-1, Editor Group 1
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
Build screenpipe data UI…, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: [IP_ADDRESS]
SSH: [IP_ADDRESS]
No Problems
0
0
No Ports Forwarded
0
Update is ready, click to restart.
Update is ready, click to restart.
Notifications
Sign In
Sign In
Screen Reader Optimized
Info: Setting up SSH Host [IP_ADDRESS]: Setting up SSH tunnel
Build screenpipe data UI and summary app
Session history
New session
Message actions
lets build app around screenpipe data and db. THe idea is to have ui and data consumers. So I can run regular commands at the end ot the day (or on demand) and create soem summary.
Thinking
Thinking
Let me explore the screenpipe directory to understand what we're working with.
Bash
List screenpipe directory contents
IN
ls /volume1/screenpipe/
Copy code to clipboard
OUT
data
db.sqlite
pipes
#recycle
[rerun: b1]
Bash
List data and pipes directories
IN
ls /volume1/screenpipe/data/ | head -20 && ls /volume1/screenpipe/pipes/
Copy code to clipboard
OUT
2026-04-09
2026-04-11
ai-habits
day-recap
meeting-summary
standup-update
time-breakdown
video-export
[rerun: b2]
Bash
List tables in screenpipe SQLite database
IN
sqlite3 /volume1/screenpipe/db.sqlite ".tables"
Copy code to clipboard
OUT
_sqlx_migrations meetings
audio_chunks memories
audio_tags memories_fts
audio_transcriptions memories_fts_config
audio_transcriptions_fts memories_fts_data
audio_transcriptions_fts_config memories_fts_docsize
audio_transcriptions_fts_data memories_fts_idx
audio_transcriptions_fts_docsize ocr_text
audio_transcriptions_fts_idx pipe_executions
elements pipe_scheduler_state
elements_fts speaker_embeddings
elements_fts_config speakers
elements_fts_data tags
elements_fts_docsize ui_events
elements_fts_idx ui_events_fts
frames ui_events_fts_config
frames_fts ui_events_fts_data
frames_fts_config ui_events_fts_docsize
frames_fts_content ui_events_fts_idx
frames_fts_data video_chunks
frames_fts_docsize vision_tags
frames_fts_idx
[rerun: b3]
Bash
Get ocr_text table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(ocr_text);"
Copy code to clipboard
OUT
0|frame_id|INTEGER|1||0
1|text|TEXT|1||0
2|text_json|TEXT|0||0
3|app_name|TEXT|1|''|0
4|ocr_engine|TEXT|1|'unknown'|0
5|window_name|TEXT|0||0
6|focused|BOOLEAN|0|FALSE|0
7|text_length|INTEGER|0||0
8|sync_id|TEXT|0||0
9|synced_at|DATETIME|0||0
[rerun: b4]
Bash
Get audio_transcriptions table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(audio_transcriptions);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|audio_chunk_id|INTEGER|1||0
2|offset_index|INTEGER|1||0
3|timestamp|TIMESTAMP|1||0
4|transcription|TEXT|1||0
5|device|TEXT|1|''|0
6|is_input_device|BOOLEAN|1|TRUE|0
7|speaker_id|INTEGER|0||0
8|transcription_engine|TEXT|1|'Whisper'|0
9|start_time|REAL|0||0
10|end_time|REAL|0||0
11|text_length|INTEGER|0||0
12|sync_id|TEXT|0||0
13|synced_at|DATETIME|0||0
[rerun: b5]
Bash
Get frames, ui_events, video_chunks schemas
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(frames); PRAGMA table_info(ui_events); PRAGMA table_info(video_chunks);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|video_chunk_id|INTEGER|0|NULL|0
2|offset_index|INTEGER|1|0|0
3|timestamp|TIMESTAMP|1||0
4|name|TEXT|0||0
5|app_name|TEXT|0|NULL|0
6|window_name|TEXT|0|NULL|0
7|focused|BOOLEAN|0|NULL|0
8|browser_url|TEXT|0|NULL|0
9|device_name|TEXT|1|''|0
10|sync_id|TEXT|0||0
11|machine_id|TEXT|0||0
12|synced_at|DATETIME|0||0
13|snapshot_path|TEXT|0|NULL|0
14|accessibility_text|TEXT|0|NULL|0
15|accessibility_tree_json|TEXT|0|NULL|0
16|content_hash|INTEGER|0|NULL|0
17|simhash|INTEGER|0|NULL|0
18|capture_trigger|TEXT|0|NULL|0
19|text_source|TEXT|0|NULL|0
20|cloud_blob_id|TEXT|0|NULL|0
21|full_text|TEXT|0|NULL|0
22|elements_ref_frame_id|INTEGER|0|NULL|0
0|id|INTEGER|0||1
1|timestamp|DATETIME|1|CURRENT_TIMESTAMP|0
2|session_id|TEXT|0||0
3|relative_ms|INTEGER|1|0|0
4|event_type|TEXT|1||0
5|x|INTEGER|0||0
6|y|INTEGER|0||0
7|delta_x|INTEGER|0||0
8|delta_y|INTEGER|0||0
9|button|INTEGER|0||0
10|click_count|INTEGER|0||0
11|key_code|INTEGER|0||0
12|modifiers|INTEGER|0||0
13|text_content|TEXT|0||0
14|text_length|INTEGER|0||0
15|app_name|TEXT|0||0
16|app_pid|INTEGER|0||0
17|window_title|TEXT|0||0
18|browser_url|TEXT|0||0
19|element_role|TEXT|0||0
20|element_name|TEXT|0||0
21|element_value|TEXT|0||0
22|element_description|TEXT|0||0
23|element_automation_id|TEXT|0||0
24|element_bounds|TEXT|0||0
25|frame_id|INTEGER|0||0
26|sync_id|TEXT|0||0
27|machine_id|TEXT|0||0
28|synced_at|DATETIME|0||0
0|id|INTEGER|0||1
1|file_path|TEXT|1||0
2|device_name|TEXT|1|''|0
3|sync_id|TEXT|0||0
4|machine_id|TEXT|0||0
5|synced_at|DATETIME|0||0
6|fps|REAL|1|0.5|0
7|cloud_blob_id|TEXT|0|NULL|0
[rerun: b6]
Bash
Check data counts and date ranges
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM frames;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM audio_transcriptions;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*) FROM ocr_text;" 2>/dev/null
Copy code to clipboard
OUT
1135|2026-04-09T16:53:09.043761+00:00|2026-04-11T12:54:42.597794+00:00
3|2026-04-09T16:53:20+00:00|2026-04-09T17:02:52+00:00
666
[rerun: b7]
Bash
Explore existing pipes for patterns
IN
ls /volume1/screenpipe/pipes/day-recap/ 2>/dev/null && cat /volume1/screenpipe/pipes/day-recap/*.js 2>/dev/null | head -50
Copy code to clipboard
OUT
pipe.md
[rerun: b8]
Bash
Read day-recap pipe documentation
IN
cat /volume1/screenpipe/pipes/day-recap/pipe.md
Copy code to clipboard
OUT
---
schedule: manual
enabled: true
template: true
title: Day Recap
description: "Today's accomplishments, key moments, and unfinished work"
icon: "📋"
featured: true
---
Analyze my screen and audio recordings from today (last 16 hours only).
Read screenpipe skill first.
Use this exact format:
## Summary
One sentence: what I mainly did today.
## Accomplishments
- Top 3 things I finished, with timestamps (e.g. "2:30 PM")
- Name specific apps, files, or projects
## Key Moments
- Important things I saw, said, or heard — with timestamps
## Unfinished Work
- What I should continue tomorrow — name the app/file/task
## Patterns
- Apps I used most, topics that came up repeatedly
Only report what you can verify from the data. End with: "**Next step:** [most important thing to continue]"
[rerun: b9]
Bash
Sample app names from frames
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT DISTINCT app_name FROM frames WHERE app_name != '' LIMIT 20;"
Copy code to clipboard
OUT
Safari
Activity Monitor
Dia
iTerm2
Control Centre
UserNotificationCenter
Finder
Claude
Slack
Firefox
Raycast
NetAuthAgent
QuickTime Player
[rerun: b10]
Bash
Sample joined frame+ocr data for today
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT f.timestamp, o.app_name, o.window_name, substr(o.text, 1, 100) as text FROM frames f JOIN ocr_text o ON f.id = o.frame_id WHERE DATE(f.timestamp) = '2026-04-11' LIMIT 5;"
Copy code to clipboard
OUT
2026-04-11T11:53:00.627698+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <47H5Sat 11 Apr 14:53:00-zshDOCKE
2026-04-11T11:53:02.005967+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <7H5Sat 11 Apr 14:53:01-zshDOCKER
2026-04-11T11:53:03.627468+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:03-zshDOCKERuse p
2026-04-11T11:53:05.528794+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:05-zshDOCKERuse p
2026-04-11T11:53:07.662098+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <7Sat 11 Apr 14:53:07-zshDOCKERuse pi
[rerun: b11]
Bash
Sample recent audio transcriptions
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT timestamp, substr(transcription,1,100) as text, device FROM audio_transcriptions ORDER BY timestamp DESC LIMIT 5;"
Copy code to clipboard
OUT
2026-04-09T17:02:52+00:00|.|System Audio
2026-04-09T16:59:22+00:00|Class is technically...|System Audio
2026-04-09T16:53:20+00:00|I do for you. Run the credit check. Deal apartment. Okay.|System Audio
[rerun: b12]
Thinking
Thinking
Good data to work with. Here's what we have:
frames
+
ocr_text
: Screen captures with OCR text, app name, window name (1135 frames so far)
audio_transcriptions
: Voice/system audio transcripts
ui_events
: Mouse/keyboard events with app context
video_chunks
: Raw video files
Before I start building, a few quick questions:
Tech stack
— Python OK? (FastAPI for the web UI backend, Click for CLI commands, HTMX for the frontend to keep it simple)
AI summaries
— Do you have a Claude API key to use for generating the actual summaries? Or should I integrate with a local model / skip AI for now?
What summaries matter most?
Day recap (what apps/windows you used, key text seen)
App time breakdown (time per app)
Audio/conversation recap
Custom searchable timeline
Here's the architecture I'm thinking:
Copy code to clipboard
/volume1/screenpipe/app/
├── main.py # FastAPI web UI
├── cli.py # Click CLI: `python cli.py day-recap`
├── db.py # Read-only queries against db.sqlite
├── consumers/
│ ├── activity.py # App usage, time per window
│ ├── ocr.py # OCR text aggregation + search
│ ├── audio.py # Transcription queries
│ └── summary.py # AI summary builder
└── static/
└── index.html # Single-page UI
CLI commands would look like:
Copy code to clipboard
python cli.py day-recap # EOD summary
python cli.py activity --date today # App time breakdown
python cli.py search "docker" # Search OCR/audio text
python cli.py serve # Launch web UI
Does this direction work? Any preferences on the stack or which summaries to prioritize?
Message actions
seesm ok
Thinking
Thinking
Bash
Check Python and available packages
IN
python3 --version && pip3 list 2>/dev/null | grep -E "fastapi|uvicorn|click|anthropic|httpx|jinja"
Copy code to clipboard
OUT
Python 3.11.2
[rerun: b1]
Bash
Verify join works for today's data
IN
sqlite3 /volume1/screenpipe/db.sqlite "
SELECT f.timestamp, o.app_name, o.window_name, length(o.text) as txt_len
FROM frames f JOIN ocr_text o ON f.id = o.frame_id
WHERE DATE(f.timestamp) = '2026-04-11'
ORDER BY f.timestamp DESC LIMIT 3;
"
Copy code to clipboard
OUT
2026-04-11T12:54:42.597794+00:00|||2111
2026-04-11T12:54:41.915916+00:00|||2110
2026-04-11T12:54:39.912712+00:00|||2111
[rerun: b2]
Bash
Install required packages
IN
pip3 install fastapi uvicorn click anthropic python-dotenv 2>&1 | tail -5
Copy code to clipboard
OUT
/bin/bash: line 1: pip3: command not found
[rerun: b3]
Bash
Find pip
IN
which pip || which pip3 || python3 -m pip --version 2>/dev/null
Copy code to clipboard
OUT
Exit code 1
[rerun: b4]
Bash
Bootstrap pip then install packages
IN
python3 -m ensurepip --upgrade 2>&1 && python3 -m pip install fastapi uvicorn click anthropic python-dotenv 2>&1 | tail -10
Copy code to clipboard
OUT
Exit code 1
/usr/bin/python3: No module named ensurepip
[rerun: b5]
Bash
Install pip via apt
IN
apt-get install -y python3-pip python3-venv 2>&1 | tail -5
Copy code to clipboard
OUT
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
[rerun: b6]
Bash
Install pip with sudo
Reason:
lets make it in docker, not to install it in nas directly
IN
sudo apt-get install -y python3-pip python3-venv 2>&1 | tail -5
Copy code to clipboard
Good call. Let me check what Docker setup you already have and build a proper containerized app.
Bash
Check existing docker-compose for reference
IN
ls /volume2/docker/paperlessngx/ && cat /volume2/docker/paperlessngx/docker-compose.yml 2>/dev/null | head -30
Copy code to clipboard
OUT
consume
data
db
docker-compose.yml
export
mcp-server
media
redis
trash
services:
redis:
image: redis:8
command:
- /bin/sh
- -c
- redis-server --requirepass redispass
container_name: PaperlessNGX-REDIS
hostname: paper-redis
security_opt:
- no-new-privileges:true
read_only: true
user: 1000:10
healthcheck:
test: ["CMD-SHELL", "redis-cli ping || exit 1"]
volumes:
- /volume2/docker/paperlessngx/redis:/data:rw
environment:
TZ: Europe/Sofia
restart: always
db:
image: postgres:17
container_name: PaperlessNGX-DB
hostname: paper-db
mem_limit: 1g
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "pg_isready", "-q", "-d", "paperless", "-U", "paperlessuser"]
[rerun: b7]
Bash
Check Docker availability
IN
docker --version && docker compose version 2>/dev/null
Copy code to clipboard
OUT
Docker version 26.1.0, build 9714adc
Docker Compose version v2.26.1
[rerun: b8]
Bash
Create app directory structure
IN
mkdir -p /volume1/screenpipe/app/consumers /volume1/screenpipe/app/static
Copy code to clipboard
OUT
[rerun: b9]
Now let me build everything. I'll create all the files:
Write
requirements.txt
requirements.txt
6 lines
fastapi==0.115.12
uvicorn[standard]==0.34.0
click==8.1.8
anthropic==0.49.0
python-dotenv==1.1.0
Write
Dockerfile
Dockerfile
13 lines
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "[IP_ADDRESS]", "--port", "8000"]
Write
db.py
db.py
28 lines
import sqlite3
from contextlib import contextmanager
from datetime import date, datetime, timedelta, timezone
from typing import Generator
DB_PATH = "/data/db.sqlite"
@contextmanager
def get_conn() -> Generator[sqlite3.Connection, None, None]:
conn = sqlite3.connect(f"file:{DB_PATH}?mode=ro", uri=True)
conn.row_factory = sqlite3.Row
try:
yield conn
finally:
conn.close()
def date_range(for_date: date) -> tuple[str, str]:
"""Return ISO timestamps for start/end of a given date (UTC)."""
start = datetime(for_date.year, for_date.month, for_date.day, tzinfo=timezone.utc)
end = start + timedelta(days=1)
return start.isoformat(), end.isoformat()
def today() -> date:
return datetime.now(timezone.utc).date()
Write
__init__.py
__init__.py
1 line
Write
activity.py
activity.py
123 lines
"""App usage and window focus time consumer."""
from datetime import date
from typing import Any
from db import get_conn, date_range, today as _today
def app_time(for_date: date | None = None) -> list[dict[str, Any]]:
"""Return minutes spent per app for a given date, sorted descending."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT
o.app_name,
COUNT(*) as frame_count,
-- each frame ~ 2s at 0.5fps; convert to minutes
ROUND(COUNT(*) * 2.0 / 60, 1) as minutes
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
GROUP BY o.app_name
ORDER BY frame_count DESC
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
def window_time(for_date: date | None = None, app: str | None = None) -> list[dict[str, Any]]:
"""Return minutes spent per window/tab, optionally filtered by app."""
d = for_date or _today()
start, end = date_range(d)
query = """
SELECT
o.app_name,
o.window_name,
COUNT(*) as frame_count,
ROUND(COUNT(*) * 2.0 / 60, 1) as minutes
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
"""
params: list = [start, end]
if app:
query += " AND o.app_name = ?"
params.append(app)
query += " GROUP BY o.app_name, o.window_name ORDER BY frame_count DESC LIMIT 50"
with get_conn() as conn:
rows = conn.execute(query, params).fetchall()
return [dict(r) for r in rows]
def timeline(for_date: date | None = None, interval_minutes: int = 15) -> list[dict[str, Any]]:
"""Return activity bucketed into N-minute intervals."""
d = for_date or _today()
start, end = date_range(d)
interval_sec = interval_minutes * 60
with get_conn() as conn:
rows = conn.execute(
f"""
SELECT
datetime(
(strftime('%s', f.timestamp) / {interval_sec}) * {interval_sec},
'unixepoch'
) as bucket,
o.app_name,
COUNT(*) as frames
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
GROUP BY bucket, o.app_name
ORDER BY bucket, frames DESC
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
def summary_stats(for_date: date | None = None) -> dict[str, Any]:
"""Return high-level stats for a date."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
frames_row = conn.execute(
"SELECT COUNT(*) as n, MIN(timestamp) as first, MAX(timestamp) as last "
"FROM frames WHERE timestamp >= ? AND timestamp < ?",
(start, end),
).fetchone()
app_count = conn.execute(
"""
SELECT COUNT(DISTINCT o.app_name) as n
FROM frames f JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ? AND o.app_name != ''
""",
(start, end),
).fetchone()
audio_count = conn.execute(
"SELECT COUNT(*) as n FROM audio_transcriptions "
"WHERE timestamp >= ? AND timestamp < ?",
(start, end),
).fetchone()
return {
"date": str(d),
"total_frames": frames_row["n"],
"first_seen": frames_row["first"],
"last_seen": frames_row["last"],
"unique_apps": app_count["n"],
"audio_segments": audio_count["n"],
}
Write
ocr.py
ocr.py
92 lines
"""OCR text search and aggregation consumer."""
from datetime import date
from typing import Any
from db import get_conn, date_range, today as _today
def search(query: str, for_date: date | None = None, limit: int = 50) -> list[dict[str, Any]]:
"""Full-text search OCR content."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT
f.timestamp,
o.app_name,
o.window_name,
snippet(ocr_text_fts, 0, '[', ']', '...', 20) as snippet
FROM ocr_text_fts
JOIN ocr_text o ON ocr_text_fts.rowid = o.rowid
JOIN frames f ON o.frame_id = f.id
WHERE ocr_text_fts MATCH ?
AND f.timestamp >= ? AND f.timestamp < ?
ORDER BY rank
LIMIT ?
""",
(query, start, end, limit),
).fetchall()
return [dict(r) for r in rows]
def text_for_date(for_date: date | None = None, focused_only: bool = True) -> list[dict[str, Any]]:
"""Return all OCR text for a date, optionally only focused windows."""
d = for_date or _today()
start, end = date_range(d)
query = """
SELECT
f.timestamp,
o.app_name,
o.window_name,
o.text
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
AND length(o.text) > 20
"""
params: list = [start, end]
if focused_only:
query += " AND o.focused = TRUE"
query += " ORDER BY f.timestamp"
with get_conn() as conn:
rows = conn.execute(query, params).fetchall()
return [dict(r) for r in rows]
def deduplicated_text(for_date: date | None = None, chunk_minutes: int = 5) -> list[dict[str, Any]]:
"""
Return OCR text deduplicated by time chunk + app to reduce LLM token usage.
Groups frames into N-minute buckets and returns one representative text per app per bucket.
"""
d = for_date or _today()
start, end = date_range(d)
interval_sec = chunk_minutes * 60
with get_conn() as conn:
rows = conn.execute(
f"""
SELECT
datetime(
(strftime('%s', f.timestamp) / {interval_sec}) * {interval_sec},
'unixepoch'
) as bucket,
o.app_name,
o.window_name,
substr(o.text, 1, 500) as text
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
AND length(o.text) > 20
GROUP BY bucket, o.app_name
ORDER BY bucket
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
Write
audio.py
audio.py
61 lines
"""Audio transcription consumer."""
from datetime import date
from typing import Any
from db import get_conn, date_range, today as _today
def transcriptions(for_date: date | None = None) -> list[dict[str, Any]]:
"""Return all audio transcriptions for a date."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT timestamp, transcription, device, is_input_device, speaker_id
FROM audio_transcriptions
WHERE timestamp >= ? AND timestamp < ?
AND length(transcription) > 2
ORDER BY timestamp
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
def search(query: str, for_date: date | None = None, limit: int = 30) -> list[dict[str, Any]]:
"""Search audio transcriptions."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT
a.timestamp,
a.device,
snippet(audio_transcriptions_fts, 0, '[', ']', '...', 20) as snippet
FROM audio_transcriptions_fts
JOIN audio_transcriptions a ON audio_transcriptions_fts.rowid = a.id
WHERE audio_transcriptions_fts MATCH ?
AND a.timestamp >= ? AND a.timestamp < ?
ORDER BY rank
LIMIT ?
""",
(query, start, end, limit),
).fetchall()
return [dict(r) for r in rows]
def formatted_transcript(for_date: date | None = None) -> str:
"""Return audio as a readable transcript string."""
rows = transcriptions(for_date)
if not rows:
return "(no audio transcriptions)"
lines = []
for r in rows:
label = "MIC" if r["is_input_device"] else "SYS"
lines.append(f"[{r['timestamp']}] [{label}] {r['transcription']}")
return "\n".join(lines)
Write
summary.py
summary.py
162 lines
"""AI summary generator using Claude."""
import os
from datetime import date
from typing import Any
from consumers.activity import app_time, summary_stats
from consumers.ocr import deduplicated_text
from consumers.audio import formatted_transcript
SUMMARY_TYPES = {
"day_recap": {
"title": "Day Recap",
"prompt": """\
You are analyzing a person's computer activity for the day.
## App usage (minutes per app):
{app_time}
## Screen content (sampled every 5 minutes):
{ocr_text}
## Audio/speech:
{audio}
Write a concise day recap using EXACTLY this format:
## Summary
One sentence: what I mainly worked on today.
## Accomplishments
- Top 3 things I finished, with approximate times
- Name specific apps, files, or projects
## Key Moments
- Important things seen or heard, with timestamps
## Unfinished Work
- What to continue tomorrow
## Patterns
- Apps used most, topics that came up repeatedly
Only report what you can verify from the data. End with:
**Next step:** [most important thing to continue]""",
},
"standup": {
"title": "Standup Update",
"prompt": """\
You are analyzing a person's computer activity for the day.
## App usage (minutes per app):
{app_time}
## Screen content (sampled every 5 minutes):
{ocr_text}
## Audio/speech:
{audio}
Write a brief standup update:
**Yesterday:** What I worked on (2-3 bullets)
**Today:** What I plan to continue (1-2 bullets)
**Blockers:** Any issues observed (or "None")
Keep it under 150 words. Only report what's verifiable from the data.""",
},
"focus_time": {
"title": "Focus & Distraction Analysis",
"prompt": """\
You are analyzing a person's computer activity for the day.
## App usage (minutes per app):
{app_time}
## Screen content (sampled every 5 minutes):
{ocr_text}
Analyze focus vs distraction patterns:
## Deep Work Periods
- When and how long were sustained focus sessions?
- What was being worked on?
## Distractions
- Which apps/sites were used recreationally?
- How much time was lost to context switching?
## Recommendations
- 2-3 concrete suggestions to improve focus tomorrow
Be specific with times and app names.""",
},
}
def _build_context(for_date: date) -> dict[str, str]:
apps = app_time(for_date)
app_lines = "\n".join(f"- {a['app_name']}: {a['minutes']} min" for a in apps[:20])
ocr_rows = deduplicated_text(for_date, chunk_minutes=5)
ocr_lines = "\n".join(
f"[{r['bucket']}] {r['app_name']} / {r['window_name'] or ''}: {r['text'][:200]}"
for r in ocr_rows[:100]
)
audio = formatted_transcript(for_date)
return {
"app_time": app_lines or "(no app data)",
"ocr_text": ocr_lines or "(no screen data)",
"audio": audio[:3000] if len(audio) > 3000 else audio,
}
def generate(
summary_type: str = "day_recap",
for_date: date | None = None,
api_key: str | None = None,
) -> dict[str, Any]:
"""Generate an AI summary. Returns dict with 'title', 'content', 'date'."""
import anthropic
d = for_date or date.today()
key = api_key or os.environ.get("ANTHROPIC_API_KEY", "")
if not key:
return {
"title": "Error",
"content": "ANTHROPIC_API_KEY not set. Add it to your .env file.",
"date": str(d),
}
spec = SUMMARY_TYPES.get(summary_type)
if not spec:
return {"title": "Error", "content": f"Unknown summary type: {summary_type}", "date": str(d)}
stats = summary_stats(d)
if stats["total_frames"] == 0:
return {
"title": spec["title"],
"content": f"No screen data found for {d}.",
"date": str(d),
}
ctx = _build_context(d)
prompt = spec["prompt"].format(**ctx)
client = anthropic.Anthropic(api_key=key)
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
)
return {
"title": spec["title"],
"content": message.content[0].text,
"date": str(d),
"stats": stats,
}
Now the FastAPI backend and CLI:
Write
main.py
main.py
89 lines
"""Screenpipe dashboard — FastAPI web UI."""
import os
from datetime import date, datetime
from typing import Any
from dotenv import load_dotenv
from fastapi import FastAPI, Query
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
load_dotenv()
from consumers.activity import app_time, window_time, timeline, summary_stats
from consumers.ocr import search as ocr_search
from consumers.audio import transcriptions, search as audio_search
from consumers.summary import generate as gen_summary, SUMMARY_TYPES
app = FastAPI(title="Screenpipe Dashboard")
app.mount("/static", StaticFiles(directory="static"), name="static")
def _parse_date(d: str | None) -> date | None:
if not d:
return None
try:
return date.fromisoformat(d)
except ValueError:
return None
@app.get("/", response_class=HTMLResponse)
async def index():
with open("static/index.html") as f:
return f.read()
# ── Activity ──────────────────────────────────────────────────────────────────
@app.get("/api/stats")
async def stats(d: str | None = Query(None)):
return summary_stats(_parse_date(d))
@app.get("/api/activity/apps")
async def activity_apps(d: str | None = Query(None)):
return app_time(_parse_date(d))
@app.get("/api/activity/windows")
async def activity_windows(d: str | None = Query(None), app_name: str | None = Query(None)):
return window_time(_parse_date(d), app_name)
@app.get("/api/activity/timeline")
async def activity_timeline(d: str | None = Query(None), interval: int = Query(15)):
return timeline(_parse_date(d), interval)
# ── Search ───────────────────────────────────────────────────────────────────
@app.get("/api/search/ocr")
async def search_ocr(q: str, d: str | None = Query(None), limit: int = 50):
return ocr_search(q, _parse_date(d), limit)
@app.get("/api/search/audio")
async def search_audio_endpoint(q: str, d: str | None = Query(None), limit: int = 30):
return audio_search(q, _parse_date(d), limit)
# ── Audio ─────────────────────────────────────────────────────────────────────
@app.get("/api/audio")
async def audio(d: str | None = Query(None)):
return transcriptions(_parse_date(d))
# ── Summaries ─────────────────────────────────────────────────────────────────
@app.get("/api/summary/types")
async def summary_types():
return [{"id": k, "title": v["title"]} for k, v in SUMMARY_TYPES.items()]
@app.post("/api/summary/generate")
async def generate_summary(type: str = "day_recap", d: str | None = None):
result = gen_summary(type, _parse_date(d))
return result
Write
cli.py
cli.py
131 lines
#!/usr/bin/env python3
"""Screenpipe CLI — run summaries and reports on demand."""
import os
import sys
from datetime import date, timedelta
import click
from dotenv import load_dotenv
load_dotenv()
sys.path.insert(0, os.path.dirname(__file__))
from consumers.activity import app_time, window_time, summary_stats
from consumers.ocr import search as ocr_search
from consumers.audio import transcriptions
from consumers.summary import generate as gen_summary, SUMMARY_TYPES
def _resolve_date(d_str: str | None) -> date | None:
if not d_str:
return None
if d_str == "yesterday":
return date.today() - timedelta(days=1)
if d_str == "today":
return date.today()
return date.fromisoformat(d_str)
@click.group()
def cli():
"""Screenpipe data explorer and summariser."""
@cli.command()
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
@click.option("--type", "-t", "summary_type", default="day_recap",
type=click.Choice(list(SUMMARY_TYPES.keys())), show_default=True)
def summary(d, summary_type):
"""Generate an AI summary for a date (default: today)."""
target = _resolve_date(d)
click.echo(f"Generating {SUMMARY_TYPES[summary_type]['title']} for {target or date.today()}...")
result = gen_summary(summary_type, target)
click.echo(f"\n{'─'*60}")
click.echo(f" {result['title']} — {result['date']}")
click.echo(f"{'─'*60}\n")
click.echo(result["content"])
if "stats" in result:
s = result["stats"]
click.echo(f"\n[data: {s['total_frames']} frames, {s['unique_apps']} apps, "
f"{s['audio_segments']} audio segments]")
@cli.command()
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
@click.option("--app", "-a", default=None, help="Filter by app name")
@click.option("--windows", "-w", is_flag=True, help="Show window breakdown instead of apps")
def activity(d, app, windows):
"""Show time spent per app or window."""
target = _resolve_date(d)
label = str(target or date.today())
if windows or app:
rows = window_time(target, app)
click.echo(f"\nWindow time — {label}" + (f" [{app}]" if app else ""))
click.echo(f"{'App':<25} {'Window':<40} {'Min':>6}")
click.echo("─" * 75)
for r in rows:
click.echo(f"{r['app_name']:<25} {(r['window_name'] or '')[:40]:<40} {r['minutes']:>6}")
else:
rows = app_time(target)
stats = summary_stats(target)
click.echo(f"\nApp time — {label}")
click.echo(f"{'App':<30} {'Minutes':>8}")
click.echo("─" * 40)
for r in rows:
click.echo(f"{r['app_name']:<30} {r['minutes']:>8}")
click.echo(f"\nTotal frames: {stats['total_frames']} | "
f"Active: {stats['first_seen']} → {stats['last_seen']}")
@cli.command()
@click.argument("query")
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
@click.option("--audio", is_flag=True, help="Search audio instead of screen text")
@click.option("--limit", "-n", default=20, show_default=True)
def search(query, d, audio, limit):
"""Search OCR screen text or audio transcriptions."""
from consumers.audio import search as audio_search_fn
target = _resolve_date(d)
if audio:
rows = audio_search_fn(query, target, limit)
click.echo(f"\nAudio results for '{query}':")
for r in rows:
click.echo(f" [{r['timestamp']}] {r['snippet']}")
else:
rows = ocr_search(query, target, limit)
click.echo(f"\nOCR results for '{query}':")
for r in rows:
click.echo(f" [{r['timestamp']}] {r['app_name']} / {r['window_name'] or ''}")
click.echo(f" {r['snippet']}")
@cli.command()
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
def audio(d):
"""Show audio transcriptions for a date."""
target = _resolve_date(d)
rows = transcriptions(target)
if not rows:
click.echo("No audio transcriptions found.")
return
click.echo(f"\nAudio transcriptions — {target or date.today()}")
click.echo("─" * 60)
for r in rows:
label = "MIC" if r["is_input_device"] else "SYS"
click.echo(f"[{r['timestamp']}] [{label}] {r['transcription']}")
@cli.command()
def serve():
"""Start the web UI (runs uvicorn on port 8000)."""
import uvicorn
click.echo("Starting Screenpipe dashboard at [URL_WITH_CREDENTIALS] (max-width: 800px) { .grid-2 { grid-template-columns: 1fr; } }
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
padding: 16px;
}
.card h2 { font-size: 13px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px; }
.bar-item { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.bar-item .name { width: 130px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 13px; }
.bar-item .bar-wrap { flex: 1; background: var(--border); border-radius: 4px; height: 12px; overflow: hidden; }
.bar-item .bar-fill { height: 100%; background: var(--accent); border-radius: 4px; transition: width 0.4s; }
.bar-item .mins { width: 50px; text-align: right; color: var(--muted); font-size: 12px; }
table { width: 100%; border-collapse: collapse; font-size: 13px; }
th { text-align: left; color: var(--muted); font-weight: 500; padding: 6px 8px; border-bottom: 1px solid var(--border); font-size: 11px; text-transform: uppercase; }
td { padding: 6px 8px; border-bottom: 1px solid var(--border); }
tr:last-child td { border-bottom: none; }
tr:hover td { background: rgba(255,255,255,0.02); }
.timeline-wrap { overflow-x: auto; }
.timeline-grid { display: grid; gap: 2px; min-width: 600px; }
.tl-row { display: flex; align-items: center; gap: 4px; margin-bottom: 2px; }
.tl-label { width: 70px; font-size: 11px; color: var(--muted); text-align: right; flex-shrink: 0; }
.tl-cell {
flex: 1;
height: 20px;
border-radius: 3px;
background: var(--border);
position: relative;
cursor: default;
font-size: 10px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
color: white;
}
.summary-controls { display: flex; gap: 10px; align-items: center; margin-bottom: 16px; flex-wrap: wrap; }
select {
background: var(--bg);
border: 1px solid var(--border);
color: var(--text);
padding: 6px 10px;
border-radius: 6px;
font-size: 13px;
}
button {
background: var(--accent);
color: white;
border: none;
padding: 8px 18px;
border-radius: 6px;
cursor: pointer;
font-size: 13px;
font-weight: 500;
}
button:hover { opacity: 0.85; }
button:disabled { opacity: 0.4; cursor: default; }
.summary-output {
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
padding: 20px;
white-space: pre-wrap;
font-family: inherit;
line-height: 1.6;
min-height: 200px;
color: var(--text);
}
.summary-output h2 { font-size: 15px; color: var(--accent); margin: 12px 0 6px; }
.summary-output ul { padding-left: 20px; }
.summary-output strong { color: var(--accent2); }
.search-bar { display: flex; gap: 8px; margin-bottom: 16px; }
.search-bar input[type="text"] { flex: 1; }
.search-bar select { }
.result-item {
border-bottom: 1px solid var(--border);
padding: 10px 4px;
}
.result-item:last-child { border-bottom: none; }
.result-meta { font-size: 11px; color: var(--muted); margin-bottom: 4px; }
.result-snippet { font-size: 13px; }
.result-snippet mark { background: rgba(124,111,205,0.3); color: var(--accent); border-radius: 2px; }
.audio-item { padding: 8px 4px; border-bottom: 1px solid var(--border); display: flex; gap: 10px; }
.audio-item:last-child { border-bottom: none; }
.audio-badge {
font-size: 10px;
padding: 2px 6px;
border-radius: 4px;
flex-shrink: 0;
font-weight: 600;
}
.audio-badge.mic { background: rgba(76,175,136,0.2); color: var(--green); }
.audio-badge.sys { background: rgba(74,163,224,0.2); ...
|
Code
|
Build screenpipe data UI… — screenpipe [SSH: 100.7 Build screenpipe data UI… — screenpipe [SSH: 100.73.206.126]...
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(ahl-zshDOCKERdeepgram keylanguages• 881DEV (-zsh)not setall languagesО ₴2APP (-zsh)• *3-zsh• x4|-zsh• ₴5|-zsh886-zsh100% <7O 87Sat 11 Apr 20:27:51-zsh181• *8monitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry isenabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.3487547ZINFO screenpipe: starting UI event capture2026-04-11T20:26:05.353656ZWARNscreenpipe: pi agent install failed: bun not found - install from https://bun.sh2026-04-11T20:26:05.358540ZINFO2026-04-11T20:26:05.363864Zscreenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.378325ZINFO screenpipe_engine::ui_recorder: Starting UI event captureINFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB(2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFO2026-04-11T20:26:051.384798ZINFOscreenpipe_engine::meeting_detector: meeting V2: detection loop started (base_interval=5s, profiles=12)screenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe onport 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting visionrecordingfor monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFO2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed listscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)2026-04-11T20:26:07.067446ZINFO2026-04-11T20:26:08.752985ZINFOscreenpipe-engine::eventdriven.capture: Sonteut dedup: skipping copture for monitoo 1 (hrs -9215443531147982392, triggeravisualchange)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: localretention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)2026-04-11T20:26:55.992688ZINFO2026-04-11T20:26:57.331771ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:27:05408691ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)screenpipe_engine::snapshot_compaction: snapshot compaction: found 61eligible frames2026-04-11T20:27:09.664908ZINFOscreenpipe_engine::snapshot_compaction: snapshot compaction: 61 frames, 9.4MB 3.3MB (2.8x), 61 JPEGs deleted...
|
NULL
|
NULL
|
NULL
|
|
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update, 1 requires restart
3
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
SCREENPIPE [SSH: [IP_ADDRESS]]
#recycle
app
consumers
static
.env
cli.py
db.py
docker-compose.yml
Dockerfile
main.py
requirements.txt
data
pipes
ai-habits
pipe.md
day-recap
meeting-summary
standup-update
time-breakdown
video-export
db.sqlite
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
pipe.md, Editor Group 1
#!/bin/bash • Untitled-1, Editor Group 1
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
Build screenpipe data UI…, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: [IP_ADDRESS]
SSH: [IP_ADDRESS]
No Problems
0
0
No Ports Forwarded
0
Update is ready, click to restart.
Update is ready, click to restart.
Notifications
Sign In
Sign In
Shell Script
Editor Language Status: $(copilot) No inline suggestion available, Inline suggestions
LF
UTF-8
Spaces: 2
Ln 16, Col 1
Screen Reader Optimized
Info: Setting up SSH Host [IP_ADDRESS]: Setting up SSH tunnel
Build screenpipe data UI and summary app
Session history
New session
Message actions
lets build app around screenpipe data and db. THe idea is to have ui and data consumers. So I can run regular commands at the end ot the day (or on demand) and create soem summary.
Thinking
Thinking
Let me explore the screenpipe directory to understand what we're working with.
Bash
List screenpipe directory contents
IN
ls /volume1/screenpipe/
Copy code to clipboard
OUT
data
db.sqlite
pipes
#recycle
[rerun: b1]
Bash
List data and pipes directories
IN
ls /volume1/screenpipe/data/ | head -20 && ls /volume1/screenpipe/pipes/
Copy code to clipboard
OUT
2026-04-09
2026-04-11
ai-habits
day-recap
meeting-summary
standup-update
time-breakdown
video-export
[rerun: b2]
Bash
List tables in screenpipe SQLite database
IN
sqlite3 /volume1/screenpipe/db.sqlite ".tables"
Copy code to clipboard
OUT
_sqlx_migrations meetings
audio_chunks memories
audio_tags memories_fts
audio_transcriptions memories_fts_config
audio_transcriptions_fts memories_fts_data
audio_transcriptions_fts_config memories_fts_docsize
audio_transcriptions_fts_data memories_fts_idx
audio_transcriptions_fts_docsize ocr_text
audio_transcriptions_fts_idx pipe_executions
elements pipe_scheduler_state
elements_fts speaker_embeddings
elements_fts_config speakers
elements_fts_data tags
elements_fts_docsize ui_events
elements_fts_idx ui_events_fts
frames ui_events_fts_config
frames_fts ui_events_fts_data
frames_fts_config ui_events_fts_docsize
frames_fts_content ui_events_fts_idx
frames_fts_data video_chunks
frames_fts_docsize vision_tags
frames_fts_idx
[rerun: b3]
Bash
Get ocr_text table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(ocr_text);"
Copy code to clipboard
OUT
0|frame_id|INTEGER|1||0
1|text|TEXT|1||0
2|text_json|TEXT|0||0
3|app_name|TEXT|1|''|0
4|ocr_engine|TEXT|1|'unknown'|0
5|window_name|TEXT|0||0
6|focused|BOOLEAN|0|FALSE|0
7|text_length|INTEGER|0||0
8|sync_id|TEXT|0||0
9|synced_at|DATETIME|0||0
[rerun: b4]
Bash
Get audio_transcriptions table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(audio_transcriptions);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|audio_chunk_id|INTEGER|1||0
2|offset_index|INTEGER|1||0
3|timestamp|TIMESTAMP|1||0
4|transcription|TEXT|1||0
5|device|TEXT|1|''|0
6|is_input_device|BOOLEAN|1|TRUE|0
7|speaker_id|INTEGER|0||0
8|transcription_engine|TEXT|1|'Whisper'|0
9|start_time|REAL|0||0
10|end_time|REAL|0||0
11|text_length|INTEGER|0||0
12|sync_id|TEXT|0||0
13|synced_at|DATETIME|0||0
[rerun: b5]
Bash
Get frames, ui_events, video_chunks schemas
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(frames); PRAGMA table_info(ui_events); PRAGMA table_info(video_chunks);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|video_chunk_id|INTEGER|0|NULL|0
2|offset_index|INTEGER|1|0|0
3|timestamp|TIMESTAMP|1||0
4|name|TEXT|0||0
5|app_name|TEXT|0|NULL|0
6|window_name|TEXT|0|NULL|0
7|focused|BOOLEAN|0|NULL|0
8|browser_url|TEXT|0|NULL|0
9|device_name|TEXT|1|''|0
10|sync_id|TEXT|0||0
11|machine_id|TEXT|0||0
12|synced_at|DATETIME|0||0
13|snapshot_path|TEXT|0|NULL|0
14|accessibility_text|TEXT|0|NULL|0
15|accessibility_tree_json|TEXT|0|NULL|0
16|content_hash|INTEGER|0|NULL|0
17|simhash|INTEGER|0|NULL|0
18|capture_trigger|TEXT|0|NULL|0
19|text_source|TEXT|0|NULL|0
20|cloud_blob_id|TEXT|0|NULL|0
21|full_text|TEXT|0|NULL|0
22|elements_ref_frame_id|INTEGER|0|NULL|0
0|id|INTEGER|0||1
1|timestamp|DATETIME|1|CURRENT_TIMESTAMP|0
2|session_id|TEXT|0||0
3|relative_ms|INTEGER|1|0|0
4|event_type|TEXT|1||0
5|x|INTEGER|0||0
6|y|INTEGER|0||0
7|delta_x|INTEGER|0||0
8|delta_y|INTEGER|0||0
9|button|INTEGER|0||0
10|click_count|INTEGER|0||0
11|key_code|INTEGER|0||0
12|modifiers|INTEGER|0||0
13|text_content|TEXT|0||0
14|text_length|INTEGER|0||0
15|app_name|TEXT|0||0
16|app_pid|INTEGER|0||0
17|window_title|TEXT|0||0
18|browser_url|TEXT|0||0
19|element_role|TEXT|0||0
20|element_name|TEXT|0||0
21|element_value|TEXT|0||0
22|element_description|TEXT|0||0
23|element_automation_id|TEXT|0||0
24|element_bounds|TEXT|0||0
25|frame_id|INTEGER|0||0
26|sync_id|TEXT|0||0
27|machine_id|TEXT|0||0
28|synced_at|DATETIME|0||0
0|id|INTEGER|0||1
1|file_path|TEXT|1||0
2|device_name|TEXT|1|''|0
3|sync_id|TEXT|0||0
4|machine_id|TEXT|0||0
5|synced_at|DATETIME|0||0
6|fps|REAL|1|0.5|0
7|cloud_blob_id|TEXT|0|NULL|0
[rerun: b6]
Bash
Check data counts and date ranges
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM frames;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM audio_transcriptions;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*) FROM ocr_text;" 2>/dev/null
Copy code to clipboard
OUT
1135|2026-04-09T16:53:09.043761+00:00|2026-04-11T12:54:42.597794+00:00
3|2026-04-09T16:53:20+00:00|2026-04-09T17:02:52+00:00
666
[rerun: b7]
Bash
Explore existing pipes for patterns
IN
ls /volume1/screenpipe/pipes/day-recap/ 2>/dev/null && cat /volume1/screenpipe/pipes/day-recap/*.js 2>/dev/null | head -50
Copy code to clipboard
OUT
pipe.md
[rerun: b8]
Bash
Read day-recap pipe documentation
IN
cat /volume1/screenpipe/pipes/day-recap/pipe.md
Copy code to clipboard
OUT
---
schedule: manual
enabled: true
template: true
title: Day Recap
description: "Today's accomplishments, key moments, and unfinished work"
icon: "📋"
featured: true
---
Analyze my screen and audio recordings from today (last 16 hours only).
Read screenpipe skill first.
Use this exact format:
## Summary
One sentence: what I mainly did today.
## Accomplishments
- Top 3 things I finished, with timestamps (e.g. "2:30 PM")
- Name specific apps, files, or projects
## Key Moments
- Important things I saw, said, or heard — with timestamps
## Unfinished Work
- What I should continue tomorrow — name the app/file/task
## Patterns
- Apps I used most, topics that came up repeatedly
Only report what you can verify from the data. End with: "**Next step:** [most important thing to continue]"
[rerun: b9]
Bash
Sample app names from frames
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT DISTINCT app_name FROM frames WHERE app_name != '' LIMIT 20;"
Copy code to clipboard
OUT
Safari
Activity Monitor
Dia
iTerm2
Control Centre
UserNotificationCenter
Finder
Claude
Slack
Firefox
Raycast
NetAuthAgent
QuickTime Player
[rerun: b10]
Bash
Sample joined frame+ocr data for today
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT f.timestamp, o.app_name, o.window_name, substr(o.text, 1, 100) as text FROM frames f JOIN ocr_text o ON f.id = o.frame_id WHERE DATE(f.timestamp) = '2026-04-11' LIMIT 5;"
Copy code to clipboard
OUT
2026-04-11T11:53:00.627698+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <47H5Sat 11 Apr 14:53:00-zshDOCKE
2026-04-11T11:53:02.005967+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <7H5Sat 11 Apr 14:53:01-zshDOCKER
2026-04-11T11:53:03.627468+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:03-zshDOCKERuse p
2026-04-11T11:53:05.528794+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:05-zshDOCKERuse p
2026-04-11T11:53:07.662098+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <7Sat 11 Apr 14:53:07-zshDOCKERuse pi
[rerun: b11]
Bash
Sample recent audio transcriptions
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT timestamp, substr(transcription,1,100) as text, device FROM audio_transcriptions ORDER BY timestamp DESC LIMIT 5;"
Copy code to clipboard
OUT
2026-04-09T17:02:52+00:00|.|System Audio
2026-04-09T16:59:22+00:00|Class is technically...|System Audio
2026-04-09T16:53:20+00:00|I do for you. Run the credit check. Deal apartment. Okay.|System Audio
[rerun: b12]
Thinking
Thinking
Good data to work with. Here's what we have:
frames
+
ocr_text
: Screen captures with OCR text, app name, window name (1135 frames so far)
audio_transcriptions
: Voice/system audio transcripts
ui_events
: Mouse/keyboard events with app context
video_chunks
: Raw video files
Before I start building, a few quick questions:
Tech stack
— Python OK? (FastAPI for the web UI backend, Click for CLI commands, HTMX for the frontend to keep it simple)
AI summaries
— Do you have a Claude API key to use for generating the actual summaries? Or should I integrate with a local model / skip AI for now?
What summaries matter most?
Day recap (what apps/windows you used, key text seen)
App time breakdown (time per app)
Audio/conversation recap
Custom searchable timeline
Here's the architecture I'm thinking:
Copy code to clipboard
/volume1/screenpipe/app/
├── main.py # FastAPI web UI
├── cli.py # Click CLI: `python cli.py day-recap`
├── db.py # Read-only queries against db.sqlite
├── consumers/
│ ├── activity.py # App usage, time per window
│ ├── ocr.py # OCR text aggregation + search
│ ├── audio.py # Transcription queries
│ └── summary.py # AI summary builder
└── static/
└── index.html # Single-page UI
CLI commands would look like:
Copy code to clipboard
python cli.py day-recap # EOD summary
python cli.py activity --date today # App time breakdown
python cli.py search "docker" # Search OCR/audio text
python cli.py serve # Launch web UI
Does this direction work? Any preferences on the stack or which summaries to prioritize?
Message actions
seesm ok
Thinking
Thinking
Bash
Check Python and available packages
IN
python3 --version && pip3 list 2>/dev/null | grep -E "fastapi|uvicorn|click|anthropic|httpx|jinja"
Copy code to clipboard
OUT
Python 3.11.2
[rerun: b1]
Bash
Verify join works for today's data
IN
sqlite3 /volume1/screenpipe/db.sqlite "
SELECT f.timestamp, o.app_name, o.window_name, length(o.text) as txt_len
FROM frames f JOIN ocr_text o ON f.id = o.frame_id
WHERE DATE(f.timestamp) = '2026-04-11'
ORDER BY f.timestamp DESC LIMIT 3;
"
Copy code to clipboard
OUT
2026-04-11T12:54:42.597794+00:00|||2111
2026-04-11T12:54:41.915916+00:00|||2110
2026-04-11T12:54:39.912712+00:00|||2111
[rerun: b2]
Bash
Install required packages
IN
pip3 install fastapi uvicorn click anthropic python-dotenv 2>&1 | tail -5
Copy code to clipboard
OUT
/bin/bash: line 1: pip3: command not found
[rerun: b3]
Bash
Find pip
IN
which pip || which pip3 || python3 -m pip --version 2>/dev/null
Copy code to clipboard
OUT
Exit code 1
[rerun: b4]
Bash
Bootstrap pip then install packages
IN
python3 -m ensurepip --upgrade 2>&1 && python3 -m pip install fastapi uvicorn click anthropic python-dotenv 2>&1 | tail -10
Copy code to clipboard
OUT
Exit code 1
/usr/bin/python3: No module named ensurepip
[rerun: b5]
Bash
Install pip via apt
IN
apt-get install -y python3-pip python3-venv 2>&1 | tail -5
Copy code to clipboard
OUT
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
[rerun: b6]
Bash
Install pip with sudo
Reason:
lets make it in docker, not to install it in nas directly
IN
sudo apt-get install -y python3-pip python3-venv 2>&1 | tail -5
Copy code to clipboard
Good call. Let me check what Docker setup you already have and build a proper containerized app.
Bash
Check existing docker-compose for reference
IN
ls /volume2/docker/paperlessngx/ && cat /volume2/docker/paperlessngx/docker-compose.yml 2>/dev/null | head -30
Copy code to clipboard
OUT
consume
data
db
docker-compose.yml
export
mcp-server
media
redis
trash
services:
redis:
image: redis:8
command:
- /bin/sh
- -c
- redis-server --requirepass redispass
container_name: PaperlessNGX-REDIS
hostname: paper-redis
security_opt:
- no-new-privileges:true
read_only: true
user: 1000:10
healthcheck:
test: ["CMD-SHELL", "redis-cli ping || exit 1"]
volumes:
- /volume2/docker/paperlessngx/redis:/data:rw
environment:
TZ: Europe/Sofia
restart: always
db:
image: postgres:17
container_name: PaperlessNGX-DB
hostname: paper-db
mem_limit: 1g
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "pg_isready", "-q", "-d", "paperless", "-U", "paperlessuser"]
[rerun: b7]
Bash
Check Docker availability
IN
docker --version && docker compose version 2>/dev/null
Copy code to clipboard
OUT
Docker version 26.1.0, build 9714adc
Docker Compose version v2.26.1
[rerun: b8]
Bash
Create app directory structure
IN
mkdir -p /volume1/screenpipe/app/consumers /volume1/screenpipe/app/static
Copy code to clipboard
OUT
[rerun: b9]
Now let me build everything. I'll create all the files:
Write
requirements.txt
requirements.txt
6 lines
fastapi==0.115.12
uvicorn[standard]==0.34.0
click==8.1.8
anthropic==0.49.0
python-dotenv==1.1.0
Write
Dockerfile
Dockerfile
13 lines
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "[IP_ADDRESS]", "--port", "8000"]
Write
db.py
db.py
28 lines
import sqlite3
from contextlib import contextmanager
from datetime import date, datetime, timedelta, timezone
from typing import Generator
DB_PATH = "/data/db.sqlite"
@contextmanager
def get_conn() -> Generator[sqlite3.Connection, None, None]:
conn = sqlite3.connect(f"file:{DB_PATH}?mode=ro", uri=True)
conn.row_factory = sqlite3.Row
try:
yield conn
finally:
conn.close()
def date_range(for_date: date) -> tuple[str, str]:
"""Return ISO timestamps for start/end of a given date (UTC)."""
start = datetime(for_date.year, for_date.month, for_date.day, tzinfo=timezone.utc)
end = start + timedelta(days=1)
return start.isoformat(), end.isoformat()
def today() -> date:
return datetime.now(timezone.utc).date()
Write
__init__.py
__init__.py
1 line
Write
activity.py
activity.py
123 lines
"""App usage and window focus time consumer."""
from datetime import date
from typing import Any
from db import get_conn, date_range, today as _today
def app_time(for_date: date | None = None) -> list[dict[str, Any]]:
"""Return minutes spent per app for a given date, sorted descending."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT
o.app_name,
COUNT(*) as frame_count,
-- each frame ~ 2s at 0.5fps; convert to minutes
ROUND(COUNT(*) * 2.0 / 60, 1) as minutes
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
GROUP BY o.app_name
ORDER BY frame_count DESC
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
def window_time(for_date: date | None = None, app: str | None = None) -> list[dict[str, Any]]:
"""Return minutes spent per window/tab, optionally filtered by app."""
d = for_date or _today()
start, end = date_range(d)
query = """
SELECT
o.app_name,
o.window_name,
COUNT(*) as frame_count,
ROUND(COUNT(*) * 2.0 / 60, 1) as minutes
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
"""
params: list = [start, end]
if app:
query += " AND o.app_name = ?"
params.append(app)
query += " GROUP BY o.app_name, o.window_name ORDER BY frame_count DESC LIMIT 50"
with get_conn() as conn:
rows = conn.execute(query, params).fetchall()
return [dict(r) for r in rows]
def timeline(for_date: date | None = None, interval_minutes: int = 15) -> list[dict[str, Any]]:
"""Return activity bucketed into N-minute intervals."""
d = for_date or _today()
start, end = date_range(d)
interval_sec = interval_minutes * 60
with get_conn() as conn:
rows = conn.execute(
f"""
SELECT
datetime(
(strftime('%s', f.timestamp) / {interval_sec}) * {interval_sec},
'unixepoch'
) as bucket,
o.app_name,
COUNT(*) as frames
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
GROUP BY bucket, o.app_name
ORDER BY bucket, frames DESC
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
def summary_stats(for_date: date | None = None) -> dict[str, Any]:
"""Return high-level stats for a date."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
frames_row = conn.execute(
"SELECT COUNT(*) as n, MIN(timestamp) as first, MAX(timestamp) as last "
"FROM frames WHERE timestamp >= ? AND timestamp < ?",
(start, end),
).fetchone()
app_count = conn.execute(
"""
SELECT COUNT(DISTINCT o.app_name) as n
FROM frames f JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ? AND o.app_name != ''
""",
(start, end),
).fetchone()
audio_count = conn.execute(
"SELECT COUNT(*) as n FROM audio_transcriptions "
"WHERE timestamp >= ? AND timestamp < ?",
(start, end),
).fetchone()
return {
"date": str(d),
"total_frames": frames_row["n"],
"first_seen": frames_row["first"],
"last_seen": frames_row["last"],
"unique_apps": app_count["n"],
"audio_segments": audio_count["n"],
}
Write
ocr.py
ocr.py
92 lines
"""OCR text search and aggregation consumer."""
from datetime import date
from typing import Any
from db import get_conn, date_range, today as _today
def search(query: str, for_date: date | None = None, limit: int = 50) -> list[dict[str, Any]]:
"""Full-text search OCR content."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT
f.timestamp,
o.app_name,
o.window_name,
snippet(ocr_text_fts, 0, '[', ']', '...', 20) as snippet
FROM ocr_text_fts
JOIN ocr_text o ON ocr_text_fts.rowid = o.rowid
JOIN frames f ON o.frame_id = f.id
WHERE ocr_text_fts MATCH ?
AND f.timestamp >= ? AND f.timestamp < ?
ORDER BY rank
LIMIT ?
""",
(query, start, end, limit),
).fetchall()
return [dict(r) for r in rows]
def text_for_date(for_date: date | None = None, focused_only: bool = True) -> list[dict[str, Any]]:
"""Return all OCR text for a date, optionally only focused windows."""
d = for_date or _today()
start, end = date_range(d)
query = """
SELECT
f.timestamp,
o.app_name,
o.window_name,
o.text
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
AND length(o.text) > 20
"""
params: list = [start, end]
if focused_only:
query += " AND o.focused = TRUE"
query += " ORDER BY f.timestamp"
with get_conn() as conn:
rows = conn.execute(query, params).fetchall()
return [dict(r) for r in rows]
def deduplicated_text(for_date: date | None = None, chunk_minutes: int = 5) -> list[dict[str, Any]]:
"""
Return OCR text deduplicated by time chunk + app to reduce LLM token usage.
Groups frames into N-minute buckets and returns one representative text per app per bucket.
"""
d = for_date or _today()
start, end = date_range(d)
interval_sec = chunk_minutes * 60
with get_conn() as conn:
rows = conn.execute(
f"""
SELECT
datetime(
(strftime('%s', f.timestamp) / {interval_sec}) * {interval_sec},
'unixepoch'
) as bucket,
o.app_name,
o.window_name,
substr(o.text, 1, 500) as text
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
AND length(o.text) > 20
GROUP BY bucket, o.app_name
ORDER BY bucket
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
Write
audio.py
audio.py
61 lines
"""Audio transcription consumer."""
from datetime import date
from typing import Any
from db import get_conn, date_range, today as _today
def transcriptions(for_date: date | None = None) -> list[dict[str, Any]]:
"""Return all audio transcriptions for a date."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT timestamp, transcription, device, is_input_device, speaker_id
FROM audio_transcriptions
WHERE timestamp >= ? AND timestamp < ?
AND length(transcription) > 2
ORDER BY timestamp
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
def search(query: str, for_date: date | None = None, limit: int = 30) -> list[dict[str, Any]]:
"""Search audio transcriptions."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT
a.timestamp,
a.device,
snippet(audio_transcriptions_fts, 0, '[', ']', '...', 20) as snippet
FROM audio_transcriptions_fts
JOIN audio_transcriptions a ON audio_transcriptions_fts.rowid = a.id
WHERE audio_transcriptions_fts MATCH ?
AND a.timestamp >= ? AND a.timestamp < ?
ORDER BY rank
LIMIT ?
""",
(query, start, end, limit),
).fetchall()
return [dict(r) for r in rows]
def formatted_transcript(for_date: date | None = None) -> str:
"""Return audio as a readable transcript string."""
rows = transcriptions(for_date)
if not rows:
return "(no audio transcriptions)"
lines = []
for r in rows:
label = "MIC" if r["is_input_device"] else "SYS"
lines.append(f"[{r['timestamp']}] [{label}] {r['transcription']}")
return "\n".join(lines)
Write
summary.py
summary.py
162 lines
"""AI summary generator using Claude."""
import os
from datetime import date
from typing import Any
from consumers.activity import app_time, summary_stats
from consumers.ocr import deduplicated_text
from consumers.audio import formatted_transcript
SUMMARY_TYPES = {
"day_recap": {
"title": "Day Recap",
"prompt": """\
You are analyzing a person's computer activity for the day.
## App usage (minutes per app):
{app_time}
## Screen content (sampled every 5 minutes):
{ocr_text}
## Audio/speech:
{audio}
Write a concise day recap using EXACTLY this format:
## Summary
One sentence: what I mainly worked on today.
## Accomplishments
- Top 3 things I finished, with approximate times
- Name specific apps, files, or projects
## Key Moments
- Important things seen or heard, with timestamps
## Unfinished Work
- What to continue tomorrow
## Patterns
- Apps used most, topics that came up repeatedly
Only report what you can verify from the data. End with:
**Next step:** [most important thing to continue]""",
},
"standup": {
"title": "Standup Update",
"prompt": """\
You are analyzing a person's computer activity for the day.
## App usage (minutes per app):
{app_time}
## Screen content (sampled every 5 minutes):
{ocr_text}
## Audio/speech:
{audio}
Write a brief standup update:
**Yesterday:** What I worked on (2-3 bullets)
**Today:** What I plan to continue (1-2 bullets)
**Blockers:** Any issues observed (or "None")
Keep it under 150 words. Only report what's verifiable from the data.""",
},
"focus_time": {
"title": "Focus & Distraction Analysis",
"prompt": """\
You are analyzing a person's computer activity for the day.
## App usage (minutes per app):
{app_time}
## Screen content (sampled every 5 minutes):
{ocr_text}
Analyze focus vs distraction patterns:
## Deep Work Periods
- When and how long were sustained focus sessions?
- What was being worked on?
## Distractions
- Which apps/sites were used recreationally?
- How much time was lost to context switching?
## Recommendations
- 2-3 concrete suggestions to improve focus tomorrow
Be specific with times and app names.""",
},
}
def _build_context(for_date: date) -> dict[str, str]:
apps = app_time(for_date)
app_lines = "\n".join(f"- {a['app_name']}: {a['minutes']} min" for a in apps[:20])
ocr_rows = deduplicated_text(for_date, chunk_minutes=5)
ocr_lines = "\n".join(
f"[{r['bucket']}] {r['app_name']} / {r['window_name'] or ''}: {r['text'][:200]}"
for r in ocr_rows[:100]
)
audio = formatted_transcript(for_date)
return {
"app_time": app_lines or "(no app data)",
"ocr_text": ocr_lines or "(no screen data)",
"audio": audio[:3000] if len(audio) > 3000 else audio,
}
def generate(
summary_type: str = "day_recap",
for_date: date | None = None,
api_key: str | None = None,
) -> dict[str, Any]:
"""Generate an AI summary. Returns dict with 'title', 'content', 'date'."""
import anthropic
d = for_date or date.today()
key = api_key or os.environ.get("ANTHROPIC_API_KEY", "")
if not key:
return {
"title": "Error",
"content": "ANTHROPIC_API_KEY not set. Add it to your .env file.",
"date": str(d),
}
spec = SUMMARY_TYPES.get(summary_type)
if not spec:
return {"title": "Error", "content": f"Unknown summary type: {summary_type}", "date": str(d)}
stats = summary_stats(d)
if stats["total_frames"] == 0:
return {
"title": spec["title"],
"content": f"No screen data found for {d}.",
"date": str(d),
}
ctx = _build_context(d)
prompt = spec["prompt"].format(**ctx)
client = anthropic.Anthropic(api_key=key)
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
)
return {
"title": spec["title"],
"content": message.content[0].text,
"date": str(d),
"stats": stats,
}
Now the FastAPI backend and CLI:
Write
main.py
main.py
89 lines
"""Screenpipe dashboard — FastAPI web UI."""
import os
from datetime import date, datetime
from typing import Any
from dotenv import load_dotenv
from fastapi import FastAPI, Query
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
load_dotenv()
from consumers.activity import app_time, window_time, timeline, summary_stats
from consumers.ocr import search as ocr_search
from consumers.audio import transcriptions, search as audio_search
from consumers.summary import generate as gen_summary, SUMMARY_TYPES
app = FastAPI(title="Screenpipe Dashboard")
app.mount("/static", StaticFiles(directory="static"), name="static")
def _parse_date(d: str | None) -> date | None:
if not d:
return None
try:
return date.fromisoformat(d)
except ValueError:
return None
@app.get("/", response_class=HTMLResponse)
async def index():
with open("static/index.html") as f:
return f.read()
# ── Activity ──────────────────────────────────────────────────────────────────
@app.get("/api/stats")
async def stats(d: str | None = Query(None)):
return summary_stats(_parse_date(d))
@app.get("/api/activity/apps")
async def activity_apps(d: str | None = Query(None)):
return app_time(_parse_date(d))
@app.get("/api/activity/windows")
async def activity_windows(d: str | None = Query(None), app_name: str | None = Query(None)):
return window_time(_parse_date(d), app_name)
@app.get("/api/activity/timeline")
async def activity_timeline(d: str | None = Query(None), interval: int = Query(15)):
return timeline(_parse_date(d), interval)
# ── Search ───────────────────────────────────────────────────────────────────
@app.get("/api/search/ocr")
async def search_ocr(q: str, d: str | None = Query(None), limit: int = 50):
return ocr_search(q, _parse_date(d), limit)
@app.get("/api/search/audio")
async def search_audio_endpoint(q: str, d: str | None = Query(None), limit: int = 30):
return audio_search(q, _parse_date(d), limit)
# ── Audio ─────────────────────────────────────────────────────────────────────
@app.get("/api/audio")
async def audio(d: str | None = Query(None)):
return transcriptions(_parse_date(d))
# ── Summaries ─────────────────────────────────────────────────────────────────
@app.get("/api/summary/types")
async def summary_types():
return [{"id": k, "title": v["title"]} for k, v in SUMMARY_TYPES.items()]
@app.post("/api/summary/generate")
async def generate_summary(type: str = "day_recap", d: str | None = None):
result = gen_summary(type, _parse_date(d))
return result
Write
cli.py
cli.py
131 lines
#!/usr/bin/env python3
"""Screenpipe CLI — run summaries and reports on demand."""
import os
import sys
from datetime import date, timedelta
import click
from dotenv import load_dotenv
load_dotenv()
sys.path.insert(0, os.path.dirname(__file__))
from consumers.activity import app_time, window_time, summary_stats
from consumers.ocr import search as ocr_search
from consumers.audio import transcriptions
from consumers.summary import generate as gen_summary, SUMMARY_TYPES
def _resolve_date(d_str: str | None) -> date | None:
if not d_str:
return None
if d_str == "yesterday":
return date.today() - timedelta(days=1)
if d_str == "today":
return date.today()
return date.fromisoformat(d_str)
@click.group()
def cli():
"""Screenpipe data explorer and summariser."""
@cli.command()
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
@click.option("--type", "-t", "summary_type", default="day_recap",
type=click.Choice(list(SUMMARY_TYPES.keys())), show_default=True)
def summary(d, summary_type):
"""Generate an AI summary for a date (default: today)."""
target = _resolve_date(d)
click.echo(f"Generating {SUMMARY_TYPES[summary_type]['title']} for {target or date.today()}...")
result = gen_summary(summary_type, target)
click.echo(f"\n{'─'*60}")
click.echo(f" {result['title']} — {result['date']}")
click.echo(f"{'─'*60}\n")
click.echo(result["content"])
if "stats" in result:
s = result["stats"]
click.echo(f"\n[data: {s['total_frames']} frames, {s['unique_apps']} apps, "
f"{s['audio_segments']} audio segments]")
@cli.command()
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
@click.option("--app", "-a", default=None, help="Filter by app name")
@click.option("--windows", "-w", is_flag=True, help="Show window breakdown instead of apps")
def activity(d, app, windows):
"""Show time spent per app or window."""
target = _resolve_date(d)
label = str(target or date.today())
if windows or app:
rows = window_time(target, app)
click.echo(f"\nWindow time — {label}" + (f" [{app}]" if app else ""))
click.echo(f"{'App':<25} {'Window':<40} {'Min':>6}")
click.echo("─" * 75)
for r in rows:
click.echo(f"{r['app_name']:<25} {(r['window_name'] or '')[:40]:<40} {r['minutes']:>6}")
else:
rows = app_time(target)
stats = summary_stats(target)
click.echo(f"\nApp time — {label}")
click.echo(f"{'App':<30} {'Minutes':>8}")
click.echo("─" * 40)
for r in rows:
click.echo(f"{r['app_name']:<30} {r['minutes']:>8}")
click.echo(f"\nTotal frames: {stats['total_frames']} | "
f"Active: {stats['first_seen']} → {stats['last_seen']}")
@cli.command()
@click.argument("query")
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
@click.option("--audio", is_flag=True, help="Search audio instead of screen text")
@click.option("--limit", "-n", default=20, show_default=True)
def search(query, d, audio, limit):
"""Search OCR screen text or audio transcriptions."""
from consumers.audio import search as audio_search_fn
target = _resolve_date(d)
if audio:
rows = audio_search_fn(query, target, limit)
click.echo(f"\nAudio results for '{query}':")
for r in rows:
click.echo(f" [{r['timestamp']}] {r['snippet']}")
else:
rows = ocr_search(query, target, limit)
click.echo(f"\nOCR results for '{query}':")
for r in rows:
click.echo(f" [{r['timestamp']}] {r['app_name']} / {r['window_name'] or ''}")
click.echo(f" {r['snippet']}")
@cli.command()
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
def audio(d):
"""Show audio transcriptions for a date."""
target = _resolve_date(d)
rows = transcriptions(target)
if not rows:
click.echo("No audio transcriptions found.")
return
click.echo(f"\nAudio transcriptions — {target or date.today()}")
click.echo("─" * 60)
for r in rows:
label = "MIC" if r["is_input_device"] else "SYS"
click.echo(f"[{r['timestamp']}] [{label}] {r['transcription']}")
@cli.command()
def serve():
"""Start the web UI (runs uvicorn on port 8000)."""
import uvicorn
click.echo("Starting Screenpipe dashboard at [URL_WITH_CREDENTIALS] (max-width: 800px) { .grid-2 { grid-template-columns: 1fr; } }
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
padding: 16px;
}
.card h2 { font-size: 13px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px; }
.bar-item { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.bar-item .name { width: 130px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 13px; }
.bar-item .bar-wrap { flex: 1; background: var(--border); border-radius: 4px; height: 12px; overflow: hidden; }
.bar-item .bar-fill { height: 100%; background: var(--accent); border-radius: 4px; transition: width 0.4s; }
.bar-item .mins { width: 50px; text-align: right; color: var(--muted); font-size: 12px; }
table { width: 100%; border-collapse: collapse; font-size: 13px; }
th { text-align: left; color: var(--muted); font-weight: 500; padding: 6px 8px; border-bottom: 1px solid var(--border); font-size: 11px; text-transform: uppercase; }
td { padding: 6px 8px; border-bottom: 1px solid var(--border); }
tr:last-child td { border-bottom: none; }
tr:hover td { background: rgba(255,255,255,0.02); }
.timeline-wrap { overflow-x: auto; }
.timeline-grid { display: grid; gap: 2px; min-width: 600px; }
.tl-row { display: flex; align-items: center; gap: 4px; margin-bottom: 2px; }
.tl-label { width: 70px; font-size: 11px; color: var(--muted); text-align: right; flex-shrink: 0; }
.tl-cell {
flex: 1;
height: 20px;
border-radius: 3px;
background: var(--border);
position: relative;
cursor: default;
font-size: 10px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
color: white;
}
.summary-controls { display: flex; gap: 10px; align-items: center; margin-bottom: 16px; flex-wrap: wrap; }
select {
background: var(--bg);
border: 1px solid var(--border);
color: var(--text);
padding: 6px 10px;
border-radius: 6px;
font-size: 13px;
}
button {
background: var(--accent);
color: white;
border: none;
padding: 8px 18px;
border-radius: 6px;
cursor: pointer;
font-size: 13px;
font-weight: 500;
}
button:hover { opacity: 0.85; }
button:disabled { opacity: 0.4; cursor: default; }
.summary-output {
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
padding: 20px;
white-space: pre-wrap;
font-family: inherit;
line-height: 1.6;
min-height: 200px;
color: var(--text);
}
.summary-output h2 { font-size: 15px; color: var(--accent); margin: 12px 0 6px; }
.summary-output ul { padding-left: 20px; }
.summary-output strong { color: var(--accent2); }
.search-bar { display: flex; gap: 8px; margin-bottom: 16px; }
.search-bar input[type="text"] { flex: 1; }
.search-bar select { }
.result-item {
border-bottom: 1px solid var(--border);
padding: 10px 4px;
}
.result-item:last-child { border-bottom: none; }
.result-meta { font-size: 11px; color: var(--muted); margin-bottom: 4px; }
.result-snippet { font-size: 13px; }
.result-snippet mark { background: rgba(124,111,205,0.3); color: var(--accent); border-radius: 2px; }
.audio-item { padding: 8px 4px; border-bottom: 1px solid var(--border); display: flex; gap: 10px; }
.audio-item:last-child { border-bottom: none; }
.audio-badge {
font-size: 10px;
padding: 2px 6px;
border-radius: 4px;
flex-shrink: 0;
font-weight: 600;
}
...
|
Code
|
#!/bin/bash • Untitled-1 — screenpipe [SSH: 100.73 #!/bin/bash • Untitled-1 — screenpipe [SSH: 100.73.206.126]...
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(ahl-zshDOCKERdeepgram keylanguages• 881DEV (-zsh)not setall languagesО ₴2APP (-zsh)• *3-zsh• x4|-zsh• ₴5|-zsh886-zsh100% <7O 87Sat 11 Apr 20:27:54-zsh181• *8monitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry isenabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.3487547ZINFO screenpipe: starting UI event capture2026-04-11T20:26:05.353656ZWARNscreenpipe: pi agent install failed: bun not found - install from https://bun.sh2026-04-11T20:26:05.358540ZINFO2026-04-11T20:26:05.363864Zscreenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.378325ZINFO screenpipe_engine::ui_recorder: Starting UI event captureINFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB(2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFO2026-04-11T20:26:051.384798ZINFOscreenpipe_engine::meeting_detector: meeting V2: detection loop started (base_interval=5s, profiles=12)screenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe onport 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting visionrecordingfor monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFO2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed listscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)2026-04-11T20:26:07.067446ZINFO2026-04-11T20:26:08.752985ZINFOscreenpipe-engine::eventdriven.capture: Sonteut dedup: skipping copture for monitoo 1 (hrs -9215443531147982392, triggeravisualchange)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: localretention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)2026-04-11T20:26:55.992688ZINFO2026-04-11T20:26:57.331771ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:27:05408691ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)screenpipe_engine::snapshot_compaction: snapshot compaction: found 61eligible frames2026-04-11T20:27:09.664908ZINFOscreenpipe_engine::snapshot_compaction: snapshot compaction: 61 frames, 9.4MB 3.3MB (2.8x), 61 JPEGs deleted...
|
NULL
|
NULL
|
NULL
|
|
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update, 1 requires restart
3
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
SCREENPIPE [SSH: [IP_ADDRESS]]
#recycle
app
consumers
static
.env
cli.py
db.py
docker-compose.yml
Dockerfile
main.py
requirements.txt
data
pipes
ai-habits
pipe.md
day-recap
meeting-summary
standup-update
time-breakdown
video-export
db.sqlite
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
pipe.md, Editor Group 1
#!/bin/bash • Untitled-1, Editor Group 1
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
Build screenpipe data UI…, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: [IP_ADDRESS]
SSH: [IP_ADDRESS]
No Problems
0
0
No Ports Forwarded
0
Update is ready, click to restart.
Update is ready, click to restart.
Notifications
Sign In
Sign In
Shell Script
Editor Language Status: $(copilot) No inline suggestion available, Inline suggestions
LF
UTF-8
Spaces: 2
Ln 66, Col 1 (2524 selected)
Screen Reader Optimized
Info: Setting up SSH Host [IP_ADDRESS]: Setting up SSH tunnel
Build screenpipe data UI and summary app
Session history
New session
Message actions
lets build app around screenpipe data and db. THe idea is to have ui and data consumers. So I can run regular commands at the end ot the day (or on demand) and create soem summary.
Thinking
Thinking
Let me explore the screenpipe directory to understand what we're working with.
Bash
List screenpipe directory contents
IN
ls /volume1/screenpipe/
Copy code to clipboard
OUT
data
db.sqlite
pipes
#recycle
[rerun: b1]
Bash
List data and pipes directories
IN
ls /volume1/screenpipe/data/ | head -20 && ls /volume1/screenpipe/pipes/
Copy code to clipboard
OUT
2026-04-09
2026-04-11
ai-habits
day-recap
meeting-summary
standup-update
time-breakdown
video-export
[rerun: b2]
Bash
List tables in screenpipe SQLite database
IN
sqlite3 /volume1/screenpipe/db.sqlite ".tables"
Copy code to clipboard
OUT
_sqlx_migrations meetings
audio_chunks memories
audio_tags memories_fts
audio_transcriptions memories_fts_config
audio_transcriptions_fts memories_fts_data
audio_transcriptions_fts_config memories_fts_docsize
audio_transcriptions_fts_data memories_fts_idx
audio_transcriptions_fts_docsize ocr_text
audio_transcriptions_fts_idx pipe_executions
elements pipe_scheduler_state
elements_fts speaker_embeddings
elements_fts_config speakers
elements_fts_data tags
elements_fts_docsize ui_events
elements_fts_idx ui_events_fts
frames ui_events_fts_config
frames_fts ui_events_fts_data
frames_fts_config ui_events_fts_docsize
frames_fts_content ui_events_fts_idx
frames_fts_data video_chunks
frames_fts_docsize vision_tags
frames_fts_idx
[rerun: b3]
Bash
Get ocr_text table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(ocr_text);"
Copy code to clipboard
OUT
0|frame_id|INTEGER|1||0
1|text|TEXT|1||0
2|text_json|TEXT|0||0
3|app_name|TEXT|1|''|0
4|ocr_engine|TEXT|1|'unknown'|0
5|window_name|TEXT|0||0
6|focused|BOOLEAN|0|FALSE|0
7|text_length|INTEGER|0||0
8|sync_id|TEXT|0||0
9|synced_at|DATETIME|0||0
[rerun: b4]
Bash
Get audio_transcriptions table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(audio_transcriptions);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|audio_chunk_id|INTEGER|1||0
2|offset_index|INTEGER|1||0
3|timestamp|TIMESTAMP|1||0
4|transcription|TEXT|1||0
5|device|TEXT|1|''|0
6|is_input_device|BOOLEAN|1|TRUE|0
7|speaker_id|INTEGER|0||0
8|transcription_engine|TEXT|1|'Whisper'|0
9|start_time|REAL|0||0
10|end_time|REAL|0||0
11|text_length|INTEGER|0||0
12|sync_id|TEXT|0||0
13|synced_at|DATETIME|0||0
[rerun: b5]
Bash
Get frames, ui_events, video_chunks schemas
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(frames); PRAGMA table_info(ui_events); PRAGMA table_info(video_chunks);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|video_chunk_id|INTEGER|0|NULL|0
2|offset_index|INTEGER|1|0|0
3|timestamp|TIMESTAMP|1||0
4|name|TEXT|0||0
5|app_name|TEXT|0|NULL|0
6|window_name|TEXT|0|NULL|0
7|focused|BOOLEAN|0|NULL|0
8|browser_url|TEXT|0|NULL|0
9|device_name|TEXT|1|''|0
10|sync_id|TEXT|0||0
11|machine_id|TEXT|0||0
12|synced_at|DATETIME|0||0
13|snapshot_path|TEXT|0|NULL|0
14|accessibility_text|TEXT|0|NULL|0
15|accessibility_tree_json|TEXT|0|NULL|0
16|content_hash|INTEGER|0|NULL|0
17|simhash|INTEGER|0|NULL|0
18|capture_trigger|TEXT|0|NULL|0
19|text_source|TEXT|0|NULL|0
20|cloud_blob_id|TEXT|0|NULL|0
21|full_text|TEXT|0|NULL|0
22|elements_ref_frame_id|INTEGER|0|NULL|0
0|id|INTEGER|0||1
1|timestamp|DATETIME|1|CURRENT_TIMESTAMP|0
2|session_id|TEXT|0||0
3|relative_ms|INTEGER|1|0|0
4|event_type|TEXT|1||0
5|x|INTEGER|0||0
6|y|INTEGER|0||0
7|delta_x|INTEGER|0||0
8|delta_y|INTEGER|0||0
9|button|INTEGER|0||0
10|click_count|INTEGER|0||0
11|key_code|INTEGER|0||0
12|modifiers|INTEGER|0||0
13|text_content|TEXT|0||0
14|text_length|INTEGER|0||0
15|app_name|TEXT|0||0
16|app_pid|INTEGER|0||0
17|window_title|TEXT|0||0
18|browser_url|TEXT|0||0
19|element_role|TEXT|0||0
20|element_name|TEXT|0||0
21|element_value|TEXT|0||0
22|element_description|TEXT|0||0
23|element_automation_id|TEXT|0||0
24|element_bounds|TEXT|0||0
25|frame_id|INTEGER|0||0
26|sync_id|TEXT|0||0
27|machine_id|TEXT|0||0
28|synced_at|DATETIME|0||0
0|id|INTEGER|0||1
1|file_path|TEXT|1||0
2|device_name|TEXT|1|''|0
3|sync_id|TEXT|0||0
4|machine_id|TEXT|0||0
5|synced_at|DATETIME|0||0
6|fps|REAL|1|0.5|0
7|cloud_blob_id|TEXT|0|NULL|0
[rerun: b6]
Bash
Check data counts and date ranges
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM frames;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM audio_transcriptions;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*) FROM ocr_text;" 2>/dev/null
Copy code to clipboard
OUT
1135|2026-04-09T16:53:09.043761+00:00|2026-04-11T12:54:42.597794+00:00
3|2026-04-09T16:53:20+00:00|2026-04-09T17:02:52+00:00
666
[rerun: b7]
Bash
Explore existing pipes for patterns
IN
ls /volume1/screenpipe/pipes/day-recap/ 2>/dev/null && cat /volume1/screenpipe/pipes/day-recap/*.js 2>/dev/null | head -50
Copy code to clipboard
OUT
pipe.md
[rerun: b8]
Bash
Read day-recap pipe documentation
IN
cat /volume1/screenpipe/pipes/day-recap/pipe.md
Copy code to clipboard
OUT
---
schedule: manual
enabled: true
template: true
title: Day Recap
description: "Today's accomplishments, key moments, and unfinished work"
icon: "📋"
featured: true
---
Analyze my screen and audio recordings from today (last 16 hours only).
Read screenpipe skill first.
Use this exact format:
## Summary
One sentence: what I mainly did today.
## Accomplishments
- Top 3 things I finished, with timestamps (e.g. "2:30 PM")
- Name specific apps, files, or projects
## Key Moments
- Important things I saw, said, or heard — with timestamps
## Unfinished Work
- What I should continue tomorrow — name the app/file/task
## Patterns
- Apps I used most, topics that came up repeatedly
Only report what you can verify from the data. End with: "**Next step:** [most important thing to continue]"
[rerun: b9]
Bash
Sample app names from frames
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT DISTINCT app_name FROM frames WHERE app_name != '' LIMIT 20;"
Copy code to clipboard
OUT
Safari
Activity Monitor
Dia
iTerm2
Control Centre
UserNotificationCenter
Finder
Claude
Slack
Firefox
Raycast
NetAuthAgent
QuickTime Player
[rerun: b10]
Bash
Sample joined frame+ocr data for today
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT f.timestamp, o.app_name, o.window_name, substr(o.text, 1, 100) as text FROM frames f JOIN ocr_text o ON f.id = o.frame_id WHERE DATE(f.timestamp) = '2026-04-11' LIMIT 5;"
Copy code to clipboard
OUT
2026-04-11T11:53:00.627698+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <47H5Sat 11 Apr 14:53:00-zshDOCKE
2026-04-11T11:53:02.005967+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <7H5Sat 11 Apr 14:53:01-zshDOCKER
2026-04-11T11:53:03.627468+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:03-zshDOCKERuse p
2026-04-11T11:53:05.528794+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:05-zshDOCKERuse p
2026-04-11T11:53:07.662098+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <7Sat 11 Apr 14:53:07-zshDOCKERuse pi
[rerun: b11]
Bash
Sample recent audio transcriptions
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT timestamp, substr(transcription,1,100) as text, device FROM audio_transcriptions ORDER BY timestamp DESC LIMIT 5;"
Copy code to clipboard
OUT
2026-04-09T17:02:52+00:00|.|System Audio
2026-04-09T16:59:22+00:00|Class is technically...|System Audio
2026-04-09T16:53:20+00:00|I do for you. Run the credit check. Deal apartment. Okay.|System Audio
[rerun: b12]
Thinking
Thinking
Good data to work with. Here's what we have:
frames
+
ocr_text
: Screen captures with OCR text, app name, window name (1135 frames so far)
audio_transcriptions
: Voice/system audio transcripts
ui_events
: Mouse/keyboard events with app context
video_chunks
: Raw video files
Before I start building, a few quick questions:
Tech stack
— Python OK? (FastAPI for the web UI backend, Click for CLI commands, HTMX for the frontend to keep it simple)
AI summaries
— Do you have a Claude API key to use for generating the actual summaries? Or should I integrate with a local model / skip AI for now?
What summaries matter most?
Day recap (what apps/windows you used, key text seen)
App time breakdown (time per app)
Audio/conversation recap
Custom searchable timeline
Here's the architecture I'm thinking:
Copy code to clipboard
/volume1/screenpipe/app/
├── main.py # FastAPI web UI
├── cli.py # Click CLI: `python cli.py day-recap`
├── db.py # Read-only queries against db.sqlite
├── consumers/
│ ├── activity.py # App usage, time per window
│ ├── ocr.py # OCR text aggregation + search
│ ├── audio.py # Transcription queries
│ └── summary.py # AI summary builder
└── static/
└── index.html # Single-page UI
CLI commands would look like:
Copy code to clipboard
python cli.py day-recap # EOD summary
python cli.py activity --date today # App time breakdown
python cli.py search "docker" # Search OCR/audio text
python cli.py serve # Launch web UI
Does this direction work? Any preferences on the stack or which summaries to prioritize?
Message actions
seesm ok
Thinking
Thinking
Bash
Check Python and available packages
IN
python3 --version && pip3 list 2>/dev/null | grep -E "fastapi|uvicorn|click|anthropic|httpx|jinja"
Copy code to clipboard
OUT
Python 3.11.2
[rerun: b1]
Bash
Verify join works for today's data
IN
sqlite3 /volume1/screenpipe/db.sqlite "
SELECT f.timestamp, o.app_name, o.window_name, length(o.text) as txt_len
FROM frames f JOIN ocr_text o ON f.id = o.frame_id
WHERE DATE(f.timestamp) = '2026-04-11'
ORDER BY f.timestamp DESC LIMIT 3;
"
Copy code to clipboard
OUT
2026-04-11T12:54:42.597794+00:00|||2111
2026-04-11T12:54:41.915916+00:00|||2110
2026-04-11T12:54:39.912712+00:00|||2111
[rerun: b2]
Bash
Install required packages
IN
pip3 install fastapi uvicorn click anthropic python-dotenv 2>&1 | tail -5
Copy code to clipboard
OUT
/bin/bash: line 1: pip3: command not found
[rerun: b3]
Bash
Find pip
IN
which pip || which pip3 || python3 -m pip --version 2>/dev/null
Copy code to clipboard
OUT
Exit code 1
[rerun: b4]
Bash
Bootstrap pip then install packages
IN
python3 -m ensurepip --upgrade 2>&1 && python3 -m pip install fastapi uvicorn click anthropic python-dotenv 2>&1 | tail -10
Copy code to clipboard
OUT
Exit code 1
/usr/bin/python3: No module named ensurepip
[rerun: b5]
Bash
Install pip via apt
IN
apt-get install -y python3-pip python3-venv 2>&1 | tail -5
Copy code to clipboard
OUT
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
[rerun: b6]
Bash
Install pip with sudo
Reason:
lets make it in docker, not to install it in nas directly
IN
sudo apt-get install -y python3-pip python3-venv 2>&1 | tail -5
Copy code to clipboard
Good call. Let me check what Docker setup you already have and build a proper containerized app.
Bash
Check existing docker-compose for reference
IN
ls /volume2/docker/paperlessngx/ && cat /volume2/docker/paperlessngx/docker-compose.yml 2>/dev/null | head -30
Copy code to clipboard
OUT
consume
data
db
docker-compose.yml
export
mcp-server
media
redis
trash
services:
redis:
image: redis:8
command:
- /bin/sh
- -c
- redis-server --requirepass redispass
container_name: PaperlessNGX-REDIS
hostname: paper-redis
security_opt:
- no-new-privileges:true
read_only: true
user: 1000:10
healthcheck:
test: ["CMD-SHELL", "redis-cli ping || exit 1"]
volumes:
- /volume2/docker/paperlessngx/redis:/data:rw
environment:
TZ: Europe/Sofia
restart: always
db:
image: postgres:17
container_name: PaperlessNGX-DB
hostname: paper-db
mem_limit: 1g
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "pg_isready", "-q", "-d", "paperless", "-U", "paperlessuser"]
[rerun: b7]
Bash
Check Docker availability
IN
docker --version && docker compose version 2>/dev/null
Copy code to clipboard
OUT
Docker version 26.1.0, build 9714adc
Docker Compose version v2.26.1
[rerun: b8]
Bash
Create app directory structure
IN
mkdir -p /volume1/screenpipe/app/consumers /volume1/screenpipe/app/static
Copy code to clipboard
OUT
[rerun: b9]
Now let me build everything. I'll create all the files:
Write
requirements.txt
requirements.txt
6 lines
fastapi==0.115.12
uvicorn[standard]==0.34.0
click==8.1.8
anthropic==0.49.0
python-dotenv==1.1.0
Write
Dockerfile
Dockerfile
13 lines
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "[IP_ADDRESS]", "--port", "8000"]
Write
db.py
db.py
28 lines
import sqlite3
from contextlib import contextmanager
from datetime import date, datetime, timedelta, timezone
from typing import Generator
DB_PATH = "/data/db.sqlite"
@contextmanager
def get_conn() -> Generator[sqlite3.Connection, None, None]:
conn = sqlite3.connect(f"file:{DB_PATH}?mode=ro", uri=True)
conn.row_factory = sqlite3.Row
try:
yield conn
finally:
conn.close()
def date_range(for_date: date) -> tuple[str, str]:
"""Return ISO timestamps for start/end of a given date (UTC)."""
start = datetime(for_date.year, for_date.month, for_date.day, tzinfo=timezone.utc)
end = start + timedelta(days=1)
return start.isoformat(), end.isoformat()
def today() -> date:
return datetime.now(timezone.utc).date()
Write
__init__.py
__init__.py
1 line
Write
activity.py
activity.py
123 lines
"""App usage and window focus time consumer."""
from datetime import date
from typing import Any
from db import get_conn, date_range, today as _today
def app_time(for_date: date | None = None) -> list[dict[str, Any]]:
"""Return minutes spent per app for a given date, sorted descending."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT
o.app_name,
COUNT(*) as frame_count,
-- each frame ~ 2s at 0.5fps; convert to minutes
ROUND(COUNT(*) * 2.0 / 60, 1) as minutes
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
GROUP BY o.app_name
ORDER BY frame_count DESC
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
def window_time(for_date: date | None = None, app: str | None = None) -> list[dict[str, Any]]:
"""Return minutes spent per window/tab, optionally filtered by app."""
d = for_date or _today()
start, end = date_range(d)
query = """
SELECT
o.app_name,
o.window_name,
COUNT(*) as frame_count,
ROUND(COUNT(*) * 2.0 / 60, 1) as minutes
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
"""
params: list = [start, end]
if app:
query += " AND o.app_name = ?"
params.append(app)
query += " GROUP BY o.app_name, o.window_name ORDER BY frame_count DESC LIMIT 50"
with get_conn() as conn:
rows = conn.execute(query, params).fetchall()
return [dict(r) for r in rows]
def timeline(for_date: date | None = None, interval_minutes: int = 15) -> list[dict[str, Any]]:
"""Return activity bucketed into N-minute intervals."""
d = for_date or _today()
start, end = date_range(d)
interval_sec = interval_minutes * 60
with get_conn() as conn:
rows = conn.execute(
f"""
SELECT
datetime(
(strftime('%s', f.timestamp) / {interval_sec}) * {interval_sec},
'unixepoch'
) as bucket,
o.app_name,
COUNT(*) as frames
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
GROUP BY bucket, o.app_name
ORDER BY bucket, frames DESC
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
def summary_stats(for_date: date | None = None) -> dict[str, Any]:
"""Return high-level stats for a date."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
frames_row = conn.execute(
"SELECT COUNT(*) as n, MIN(timestamp) as first, MAX(timestamp) as last "
"FROM frames WHERE timestamp >= ? AND timestamp < ?",
(start, end),
).fetchone()
app_count = conn.execute(
"""
SELECT COUNT(DISTINCT o.app_name) as n
FROM frames f JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ? AND o.app_name != ''
""",
(start, end),
).fetchone()
audio_count = conn.execute(
"SELECT COUNT(*) as n FROM audio_transcriptions "
"WHERE timestamp >= ? AND timestamp < ?",
(start, end),
).fetchone()
return {
"date": str(d),
"total_frames": frames_row["n"],
"first_seen": frames_row["first"],
"last_seen": frames_row["last"],
"unique_apps": app_count["n"],
"audio_segments": audio_count["n"],
}
Write
ocr.py
ocr.py
92 lines
"""OCR text search and aggregation consumer."""
from datetime import date
from typing import Any
from db import get_conn, date_range, today as _today
def search(query: str, for_date: date | None = None, limit: int = 50) -> list[dict[str, Any]]:
"""Full-text search OCR content."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT
f.timestamp,
o.app_name,
o.window_name,
snippet(ocr_text_fts, 0, '[', ']', '...', 20) as snippet
FROM ocr_text_fts
JOIN ocr_text o ON ocr_text_fts.rowid = o.rowid
JOIN frames f ON o.frame_id = f.id
WHERE ocr_text_fts MATCH ?
AND f.timestamp >= ? AND f.timestamp < ?
ORDER BY rank
LIMIT ?
""",
(query, start, end, limit),
).fetchall()
return [dict(r) for r in rows]
def text_for_date(for_date: date | None = None, focused_only: bool = True) -> list[dict[str, Any]]:
"""Return all OCR text for a date, optionally only focused windows."""
d = for_date or _today()
start, end = date_range(d)
query = """
SELECT
f.timestamp,
o.app_name,
o.window_name,
o.text
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
AND length(o.text) > 20
"""
params: list = [start, end]
if focused_only:
query += " AND o.focused = TRUE"
query += " ORDER BY f.timestamp"
with get_conn() as conn:
rows = conn.execute(query, params).fetchall()
return [dict(r) for r in rows]
def deduplicated_text(for_date: date | None = None, chunk_minutes: int = 5) -> list[dict[str, Any]]:
"""
Return OCR text deduplicated by time chunk + app to reduce LLM token usage.
Groups frames into N-minute buckets and returns one representative text per app per bucket.
"""
d = for_date or _today()
start, end = date_range(d)
interval_sec = chunk_minutes * 60
with get_conn() as conn:
rows = conn.execute(
f"""
SELECT
datetime(
(strftime('%s', f.timestamp) / {interval_sec}) * {interval_sec},
'unixepoch'
) as bucket,
o.app_name,
o.window_name,
substr(o.text, 1, 500) as text
FROM frames f
JOIN ocr_text o ON f.id = o.frame_id
WHERE f.timestamp >= ? AND f.timestamp < ?
AND o.app_name != ''
AND length(o.text) > 20
GROUP BY bucket, o.app_name
ORDER BY bucket
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
Write
audio.py
audio.py
61 lines
"""Audio transcription consumer."""
from datetime import date
from typing import Any
from db import get_conn, date_range, today as _today
def transcriptions(for_date: date | None = None) -> list[dict[str, Any]]:
"""Return all audio transcriptions for a date."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT timestamp, transcription, device, is_input_device, speaker_id
FROM audio_transcriptions
WHERE timestamp >= ? AND timestamp < ?
AND length(transcription) > 2
ORDER BY timestamp
""",
(start, end),
).fetchall()
return [dict(r) for r in rows]
def search(query: str, for_date: date | None = None, limit: int = 30) -> list[dict[str, Any]]:
"""Search audio transcriptions."""
d = for_date or _today()
start, end = date_range(d)
with get_conn() as conn:
rows = conn.execute(
"""
SELECT
a.timestamp,
a.device,
snippet(audio_transcriptions_fts, 0, '[', ']', '...', 20) as snippet
FROM audio_transcriptions_fts
JOIN audio_transcriptions a ON audio_transcriptions_fts.rowid = a.id
WHERE audio_transcriptions_fts MATCH ?
AND a.timestamp >= ? AND a.timestamp < ?
ORDER BY rank
LIMIT ?
""",
(query, start, end, limit),
).fetchall()
return [dict(r) for r in rows]
def formatted_transcript(for_date: date | None = None) -> str:
"""Return audio as a readable transcript string."""
rows = transcriptions(for_date)
if not rows:
return "(no audio transcriptions)"
lines = []
for r in rows:
label = "MIC" if r["is_input_device"] else "SYS"
lines.append(f"[{r['timestamp']}] [{label}] {r['transcription']}")
return "\n".join(lines)
Write
summary.py
summary.py
162 lines
"""AI summary generator using Claude."""
import os
from datetime import date
from typing import Any
from consumers.activity import app_time, summary_stats
from consumers.ocr import deduplicated_text
from consumers.audio import formatted_transcript
SUMMARY_TYPES = {
"day_recap": {
"title": "Day Recap",
"prompt": """\
You are analyzing a person's computer activity for the day.
## App usage (minutes per app):
{app_time}
## Screen content (sampled every 5 minutes):
{ocr_text}
## Audio/speech:
{audio}
Write a concise day recap using EXACTLY this format:
## Summary
One sentence: what I mainly worked on today.
## Accomplishments
- Top 3 things I finished, with approximate times
- Name specific apps, files, or projects
## Key Moments
- Important things seen or heard, with timestamps
## Unfinished Work
- What to continue tomorrow
## Patterns
- Apps used most, topics that came up repeatedly
Only report what you can verify from the data. End with:
**Next step:** [most important thing to continue]""",
},
"standup": {
"title": "Standup Update",
"prompt": """\
You are analyzing a person's computer activity for the day.
## App usage (minutes per app):
{app_time}
## Screen content (sampled every 5 minutes):
{ocr_text}
## Audio/speech:
{audio}
Write a brief standup update:
**Yesterday:** What I worked on (2-3 bullets)
**Today:** What I plan to continue (1-2 bullets)
**Blockers:** Any issues observed (or "None")
Keep it under 150 words. Only report what's verifiable from the data.""",
},
"focus_time": {
"title": "Focus & Distraction Analysis",
"prompt": """\
You are analyzing a person's computer activity for the day.
## App usage (minutes per app):
{app_time}
## Screen content (sampled every 5 minutes):
{ocr_text}
Analyze focus vs distraction patterns:
## Deep Work Periods
- When and how long were sustained focus sessions?
- What was being worked on?
## Distractions
- Which apps/sites were used recreationally?
- How much time was lost to context switching?
## Recommendations
- 2-3 concrete suggestions to improve focus tomorrow
Be specific with times and app names.""",
},
}
def _build_context(for_date: date) -> dict[str, str]:
apps = app_time(for_date)
app_lines = "\n".join(f"- {a['app_name']}: {a['minutes']} min" for a in apps[:20])
ocr_rows = deduplicated_text(for_date, chunk_minutes=5)
ocr_lines = "\n".join(
f"[{r['bucket']}] {r['app_name']} / {r['window_name'] or ''}: {r['text'][:200]}"
for r in ocr_rows[:100]
)
audio = formatted_transcript(for_date)
return {
"app_time": app_lines or "(no app data)",
"ocr_text": ocr_lines or "(no screen data)",
"audio": audio[:3000] if len(audio) > 3000 else audio,
}
def generate(
summary_type: str = "day_recap",
for_date: date | None = None,
api_key: str | None = None,
) -> dict[str, Any]:
"""Generate an AI summary. Returns dict with 'title', 'content', 'date'."""
import anthropic
d = for_date or date.today()
key = api_key or os.environ.get("ANTHROPIC_API_KEY", "")
if not key:
return {
"title": "Error",
"content": "ANTHROPIC_API_KEY not set. Add it to your .env file.",
"date": str(d),
}
spec = SUMMARY_TYPES.get(summary_type)
if not spec:
return {"title": "Error", "content": f"Unknown summary type: {summary_type}", "date": str(d)}
stats = summary_stats(d)
if stats["total_frames"] == 0:
return {
"title": spec["title"],
"content": f"No screen data found for {d}.",
"date": str(d),
}
ctx = _build_context(d)
prompt = spec["prompt"].format(**ctx)
client = anthropic.Anthropic(api_key=key)
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
)
return {
"title": spec["title"],
"content": message.content[0].text,
"date": str(d),
"stats": stats,
}
Now the FastAPI backend and CLI:
Write
main.py
main.py
89 lines
"""Screenpipe dashboard — FastAPI web UI."""
import os
from datetime import date, datetime
from typing import Any
from dotenv import load_dotenv
from fastapi import FastAPI, Query
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
load_dotenv()
from consumers.activity import app_time, window_time, timeline, summary_stats
from consumers.ocr import search as ocr_search
from consumers.audio import transcriptions, search as audio_search
from consumers.summary import generate as gen_summary, SUMMARY_TYPES
app = FastAPI(title="Screenpipe Dashboard")
app.mount("/static", StaticFiles(directory="static"), name="static")
def _parse_date(d: str | None) -> date | None:
if not d:
return None
try:
return date.fromisoformat(d)
except ValueError:
return None
@app.get("/", response_class=HTMLResponse)
async def index():
with open("static/index.html") as f:
return f.read()
# ── Activity ──────────────────────────────────────────────────────────────────
@app.get("/api/stats")
async def stats(d: str | None = Query(None)):
return summary_stats(_parse_date(d))
@app.get("/api/activity/apps")
async def activity_apps(d: str | None = Query(None)):
return app_time(_parse_date(d))
@app.get("/api/activity/windows")
async def activity_windows(d: str | None = Query(None), app_name: str | None = Query(None)):
return window_time(_parse_date(d), app_name)
@app.get("/api/activity/timeline")
async def activity_timeline(d: str | None = Query(None), interval: int = Query(15)):
return timeline(_parse_date(d), interval)
# ── Search ───────────────────────────────────────────────────────────────────
@app.get("/api/search/ocr")
async def search_ocr(q: str, d: str | None = Query(None), limit: int = 50):
return ocr_search(q, _parse_date(d), limit)
@app.get("/api/search/audio")
async def search_audio_endpoint(q: str, d: str | None = Query(None), limit: int = 30):
return audio_search(q, _parse_date(d), limit)
# ── Audio ─────────────────────────────────────────────────────────────────────
@app.get("/api/audio")
async def audio(d: str | None = Query(None)):
return transcriptions(_parse_date(d))
# ── Summaries ─────────────────────────────────────────────────────────────────
@app.get("/api/summary/types")
async def summary_types():
return [{"id": k, "title": v["title"]} for k, v in SUMMARY_TYPES.items()]
@app.post("/api/summary/generate")
async def generate_summary(type: str = "day_recap", d: str | None = None):
result = gen_summary(type, _parse_date(d))
return result
Write
cli.py
cli.py
131 lines
#!/usr/bin/env python3
"""Screenpipe CLI — run summaries and reports on demand."""
import os
import sys
from datetime import date, timedelta
import click
from dotenv import load_dotenv
load_dotenv()
sys.path.insert(0, os.path.dirname(__file__))
from consumers.activity import app_time, window_time, summary_stats
from consumers.ocr import search as ocr_search
from consumers.audio import transcriptions
from consumers.summary import generate as gen_summary, SUMMARY_TYPES
def _resolve_date(d_str: str | None) -> date | None:
if not d_str:
return None
if d_str == "yesterday":
return date.today() - timedelta(days=1)
if d_str == "today":
return date.today()
return date.fromisoformat(d_str)
@click.group()
def cli():
"""Screenpipe data explorer and summariser."""
@cli.command()
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
@click.option("--type", "-t", "summary_type", default="day_recap",
type=click.Choice(list(SUMMARY_TYPES.keys())), show_default=True)
def summary(d, summary_type):
"""Generate an AI summary for a date (default: today)."""
target = _resolve_date(d)
click.echo(f"Generating {SUMMARY_TYPES[summary_type]['title']} for {target or date.today()}...")
result = gen_summary(summary_type, target)
click.echo(f"\n{'─'*60}")
click.echo(f" {result['title']} — {result['date']}")
click.echo(f"{'─'*60}\n")
click.echo(result["content"])
if "stats" in result:
s = result["stats"]
click.echo(f"\n[data: {s['total_frames']} frames, {s['unique_apps']} apps, "
f"{s['audio_segments']} audio segments]")
@cli.command()
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
@click.option("--app", "-a", default=None, help="Filter by app name")
@click.option("--windows", "-w", is_flag=True, help="Show window breakdown instead of apps")
def activity(d, app, windows):
"""Show time spent per app or window."""
target = _resolve_date(d)
label = str(target or date.today())
if windows or app:
rows = window_time(target, app)
click.echo(f"\nWindow time — {label}" + (f" [{app}]" if app else ""))
click.echo(f"{'App':<25} {'Window':<40} {'Min':>6}")
click.echo("─" * 75)
for r in rows:
click.echo(f"{r['app_name']:<25} {(r['window_name'] or '')[:40]:<40} {r['minutes']:>6}")
else:
rows = app_time(target)
stats = summary_stats(target)
click.echo(f"\nApp time — {label}")
click.echo(f"{'App':<30} {'Minutes':>8}")
click.echo("─" * 40)
for r in rows:
click.echo(f"{r['app_name']:<30} {r['minutes']:>8}")
click.echo(f"\nTotal frames: {stats['total_frames']} | "
f"Active: {stats['first_seen']} → {stats['last_seen']}")
@cli.command()
@click.argument("query")
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
@click.option("--audio", is_flag=True, help="Search audio instead of screen text")
@click.option("--limit", "-n", default=20, show_default=True)
def search(query, d, audio, limit):
"""Search OCR screen text or audio transcriptions."""
from consumers.audio import search as audio_search_fn
target = _resolve_date(d)
if audio:
rows = audio_search_fn(query, target, limit)
click.echo(f"\nAudio results for '{query}':")
for r in rows:
click.echo(f" [{r['timestamp']}] {r['snippet']}")
else:
rows = ocr_search(query, target, limit)
click.echo(f"\nOCR results for '{query}':")
for r in rows:
click.echo(f" [{r['timestamp']}] {r['app_name']} / {r['window_name'] or ''}")
click.echo(f" {r['snippet']}")
@cli.command()
@click.option("--date", "-d", "d", default=None, help="Date (YYYY-MM-DD, today, yesterday)")
def audio(d):
"""Show audio transcriptions for a date."""
target = _resolve_date(d)
rows = transcriptions(target)
if not rows:
click.echo("No audio transcriptions found.")
return
click.echo(f"\nAudio transcriptions — {target or date.today()}")
click.echo("─" * 60)
for r in rows:
label = "MIC" if r["is_input_device"] else "SYS"
click.echo(f"[{r['timestamp']}] [{label}] {r['transcription']}")
@cli.command()
def serve():
"""Start the web UI (runs uvicorn on port 8000)."""
import uvicorn
click.echo("Starting Screenpipe dashboard at [URL_WITH_CREDENTIALS] (max-width: 800px) { .grid-2 { grid-template-columns: 1fr; } }
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
padding: 16px;
}
.card h2 { font-size: 13px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px; }
.bar-item { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.bar-item .name { width: 130px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 13px; }
.bar-item .bar-wrap { flex: 1; background: var(--border); border-radius: 4px; height: 12px; overflow: hidden; }
.bar-item .bar-fill { height: 100%; background: var(--accent); border-radius: 4px; transition: width 0.4s; }
.bar-item .mins { width: 50px; text-align: right; color: var(--muted); font-size: 12px; }
table { width: 100%; border-collapse: collapse; font-size: 13px; }
th { text-align: left; color: var(--muted); font-weight: 500; padding: 6px 8px; border-bottom: 1px solid var(--border); font-size: 11px; text-transform: uppercase; }
td { padding: 6px 8px; border-bottom: 1px solid var(--border); }
tr:last-child td { border-bottom: none; }
tr:hover td { background: rgba(255,255,255,0.02); }
.timeline-wrap { overflow-x: auto; }
.timeline-grid { display: grid; gap: 2px; min-width: 600px; }
.tl-row { display: flex; align-items: center; gap: 4px; margin-bottom: 2px; }
.tl-label { width: 70px; font-size: 11px; color: var(--muted); text-align: right; flex-shrink: 0; }
.tl-cell {
flex: 1;
height: 20px;
border-radius: 3px;
background: var(--border);
position: relative;
cursor: default;
font-size: 10px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
color: white;
}
.summary-controls { display: flex; gap: 10px; align-items: center; margin-bottom: 16px; flex-wrap: wrap; }
select {
background: var(--bg);
border: 1px solid var(--border);
color: var(--text);
padding: 6px 10px;
border-radius: 6px;
font-size: 13px;
}
button {
background: var(--accent);
color: white;
border: none;
padding: 8px 18px;
border-radius: 6px;
cursor: pointer;
font-size: 13px;
font-weight: 500;
}
button:hover { opacity: 0.85; }
button:disabled { opacity: 0.4; cursor: default; }
.summary-output {
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
padding: 20px;
white-space: pre-wrap;
font-family: inherit;
line-height: 1.6;
min-height: 200px;
color: var(--text);
}
.summary-output h2 { font-size: 15px; color: var(--accent); margin: 12px 0 6px; }
.summary-output ul { padding-left: 20px; }
.summary-output strong { color: var(--accent2); }
.search-bar { display: flex; gap: 8px; margin-bottom: 16px; }
.search-bar input[type="text"] { flex: 1; }
.search-bar select { }
.result-item {
border-bottom: 1px solid var(--border);
padding: 10px 4px;
}
.result-item:last-child { border-bottom: none; }
.result-meta { font-size: 11px; color: var(--muted); margin-bottom: 4px; }
.result-snippet { font-size: 13px; }
.result-snippet mark { background: rgba(124,111,205,0.3); color: var(--accent); border-radius: 2px; }
.audio-item { padding: 8px 4px; border-bottom: 1px solid var(--border); display: flex; gap: 10px; }
.audio-item:last-child { border-bottom: none; }
.audio-badge {
font-size: 10px;
padding: 2px 6px;
border-radius: 4px;
flex-shrink: 0;
font-wei...
|
Code
|
#!/bin/bash • Untitled-1 — screenpipe [SSH: 100.73 #!/bin/bash • Untitled-1 — screenpipe [SSH: 100.73.206.126]...
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpall-zshDOCKERdeepgram keylanguages• 881DEV (-zsh)not setall languagesО ₴2APP (-zsh)• *3-zsh• x4|-zsh• 285-zsh886-zsh100% <7O 87Sat 11 Apr 20:27:57-zsh181• *8monitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry isenabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.3487547ZINFO screenpipe: starting UI event capture2026-04-11T20:26:05.353656ZWARNscreenpipe: pi agent install failed: bun not found - install from https://bun.sh2026-04-11T20:26:05.358540ZINFO2026-04-11T20:26:05.363864Zscreenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.378325ZINFO screenpipe_engine::ui_recorder: Starting UI event captureINFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB(2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFO2026-04-11T20:26:051.384798ZINFOscreenpipe_engine::meeting_detector: meeting V2: detection loop started (base_interval=5s, profiles=12)screenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe onport 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting visionrecordingfor monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFO2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed listscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)2026-04-11T20:26:07.067446ZINFO2026-04-11T20:26:08.752985ZINFOscreenpipe-engine::eventdriven.capture: Sonteut dedup: skipping copture for monitoo 1 (hrs -9215443531147982392, triggeravisualchange)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: localretention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)2026-04-11T20:26:55.992688ZINFO2026-04-11T20:26:57.331771ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:27:05408691ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)screenpipe_engine::snapshot_compaction: snapshot compaction: found 61eligible frames2026-04-11T20:27:09.664908ZINFOscreenpipe_engine::snapshot_compaction: snapshot compaction: 61 frames, 9.4MB 3.3MB (2.8x), 61 JPEGs deleted...
|
NULL
|
NULL
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpall100% <7-zshDOCKERdeepgram keylanguages• 881DEV (-zsh)not setall languagesО ₴2APP (-zsh)• *3-zsh• x4|-zsh• ₴5|-zsh886-zshO 87Sat 11 Apr 20:28:02-zsh181• *8monitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry isenabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.3487547ZINFO screenpipe: starting UI event capture2026-04-11T20:26:05.353656ZWARNscreenpipe: pi agent install failed: bun not found - install from https://bun.sh2026-04-11T20:26:05.358540ZINFO2026-04-11T20:26:05.363864Zscreenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.378325ZINFO screenpipe_engine::ui_recorder: Starting UI event captureINFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB(2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFO2026-04-11T20:26:051.384798ZINFOscreenpipe_engine::meeting_detector: meeting V2: detection loop started (base_interval=5s, profiles=12)screenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe onport 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting visionrecordingfor monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFO2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed listscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)2026-04-11T20:26:07.067446ZINFO2026-04-11T20:26:08.752985ZINFOscreenpipe-engine::eventdriven.capture: Sonteut dedup: skipping copture for monitoo 1 (hrs -9215443531147982392, triggeravisualchange)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: localretention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)2026-04-11T20:26:55.992688ZINFO2026-04-11T20:26:57.331771ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:27:05408691ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)screenpipe_engine::snapshot_compaction: snapshot compaction: found 61eligible frames2026-04-11T20:27:09.664908ZINFOscreenpipe_engine::snapshot_compaction: snapshot compaction: 61 frames, 9.4MB 3.3MB (2.8x), 61 JPEGs deleted...
|
NULL
|
NULL
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpall100% <7-zshDOCKERdeepgram keylanguages• 881DEV (-zsh)not setall languagesО ₴2APP (-zsh)• *3-zsh• x4|-zsh• ₴5|-zsh886-zshO 87Sat 11 Apr 20:28:19-zsh181• *8monitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry isenabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.3487547ZINFO screenpipe: starting UI event capture2026-04-11T20:26:05.353656ZWARNscreenpipe: pi agent install failed: bun not found - install from https://bun.sh2026-04-11T20:26:05.358540ZINFO2026-04-11T20:26:05.363864Zscreenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.378325ZINFO screenpipe_engine::ui_recorder: Starting UI event captureINFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB(2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFO2026-04-11T20:26:051.384798ZINFOscreenpipe_engine::meeting_detector: meeting V2: detection loop started (base_interval=5s, profiles=12)screenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe onport 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting visionrecordingfor monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFO2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed listscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)2026-04-11T20:26:07.067446ZINFO2026-04-11T20:26:08.752985ZINFOscreenpipe-engine::eventdriven.capture: Sonteut dedup: skipping copture for monitoo 1 (hrs -9215443531147982392, triggeravisualchange)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: localretention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)2026-04-11T20:26:55.992688ZINFO2026-04-11T20:26:57.331771ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:27:05408691ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)screenpipe_engine::snapshot_compaction: snapshot compaction: found 61eligible frames2026-04-11T20:27:09.664908ZINFOscreenpipe_engine::snapshot_compaction: snapshot compaction: 61 frames, 9.4MB 3.3MB (2.8x), 61 JPEGs deleted...
|
NULL
|
NULL
|
NULL
|
|
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update, 1 requires restart
3
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
SCREENPIPE [SSH: [IP_ADDRESS]]
#recycle
app
consumers
static
.env
cli.py
db.py
docker-compose.yml
Dockerfile
main.py
requirements.txt
data
pipes
ai-habits
pipe.md
day-recap
meeting-summary
standup-update
time-breakdown
video-export
db.sqlite
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
pipe.md, Editor Group 1
#!/bin/bash • Untitled-1, Editor Group 1
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
Build screenpipe data UI…, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: [IP_ADDRESS]
SSH: [IP_ADDRESS]
No Problems
0
0
No Ports Forwarded
0
Update is ready, click to restart.
Update is ready, click to restart.
Notifications
Sign In
Sign In
Screen Reader Optimized
Info: Setting up SSH Host [IP_ADDRESS]: Setting up SSH tunnel
Build screenpipe data UI and summary app
Session history
New session
Message actions
lets build app around screenpipe data and db. THe idea is to have ui and data consumers. So I can run regular commands at the end ot the day (or on demand) and create soem summary.
Thinking
Thinking
Let me explore the screenpipe directory to understand what we're working with.
Bash
List screenpipe directory contents
IN
ls /volume1/screenpipe/
Copy code to clipboard
OUT
data
db.sqlite
pipes
#recycle
[rerun: b1]
Bash
List data and pipes directories
IN
ls /volume1/screenpipe/data/ | head -20 && ls /volume1/screenpipe/pipes/
Copy code to clipboard
OUT
2026-04-09
2026-04-11
ai-habits
day-recap
meeting-summary
standup-update
time-breakdown
video-export
[rerun: b2]
Bash
List tables in screenpipe SQLite database
IN
sqlite3 /volume1/screenpipe/db.sqlite ".tables"
Copy code to clipboard
OUT
_sqlx_migrations meetings
audio_chunks memories
audio_tags memories_fts
audio_transcriptions memories_fts_config
audio_transcriptions_fts memories_fts_data
audio_transcriptions_fts_config memories_fts_docsize
audio_transcriptions_fts_data memories_fts_idx
audio_transcriptions_fts_docsize ocr_text
audio_transcriptions_fts_idx pipe_executions
elements pipe_scheduler_state
elements_fts speaker_embeddings
elements_fts_config speakers
elements_fts_data tags
elements_fts_docsize ui_events
elements_fts_idx ui_events_fts
frames ui_events_fts_config
frames_fts ui_events_fts_data
frames_fts_config ui_events_fts_docsize
frames_fts_content ui_events_fts_idx
frames_fts_data video_chunks
frames_fts_docsize vision_tags
frames_fts_idx
[rerun: b3]
Bash
Get ocr_text table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(ocr_text);"
Copy code to clipboard
OUT
0|frame_id|INTEGER|1||0
1|text|TEXT|1||0
2|text_json|TEXT|0||0
3|app_name|TEXT|1|''|0
4|ocr_engine|TEXT|1|'unknown'|0
5|window_name|TEXT|0||0
6|focused|BOOLEAN|0|FALSE|0
7|text_length|INTEGER|0||0
8|sync_id|TEXT|0||0
9|synced_at|DATETIME|0||0
[rerun: b4]
Bash
Get audio_transcriptions table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(audio_transcriptions);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|audio_chunk_id|INTEGER|1||0
2|offset_index|INTEGER|1||0
3|timestamp|TIMESTAMP|1||0
4|transcription|TEXT|1||0
5|device|TEXT|1|''|0
6|is_input_device|BOOLEAN|1|TRUE|0
7|speaker_id|INTEGER|0||0
8|transcription_engine|TEXT|1|'Whisper'|0
9|start_time|REAL|0||0
10|end_time|REAL|0||0
11|text_length|INTEGER|0||0
12|sync_id|TEXT|0||0
13|synced_at|DATETIME|0||0
[rerun: b5]
Bash
Get frames, ui_events, video_chunks schemas
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(frames); PRAGMA table_info(ui_events); PRAGMA table_info(video_chunks);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|video_chunk_id|INTEGER|0|NULL|0
2|offset_index|INTEGER|1|0|0
3|timestamp|TIMESTAMP|1||0
4|name|TEXT|0||0
5|app_name|TEXT|0|NULL|0
6|window_name|TEXT|0|NULL|0
7|focused|BOOLEAN|0|NULL|0
8|browser_url|TEXT|0|NULL|0
9|device_name|TEXT|1|''|0
10|sync_id|TEXT|0||0
11|machine_id|TEXT|0||0
12|synced_at|DATETIME|0||0
13|snapshot_path|TEXT|0|NULL|0
14|accessibility_text|TEXT|0|NULL|0
15|accessibility_tree_json|TEXT|0|NULL|0
16|content_hash|INTEGER|0|NULL|0
17|simhash|INTEGER|0|NULL|0
18|capture_trigger|TEXT|0|NULL|0
19|text_source|TEXT|0|NULL|0
20|cloud_blob_id|TEXT|0|NULL|0
21|full_text|TEXT|0|NULL|0
22|elements_ref_frame_id|INTEGER|0|NULL|0
0|id|INTEGER|0||1
1|timestamp|DATETIME|1|CURRENT_TIMESTAMP|0
2|session_id|TEXT|0||0
3|relative_ms|INTEGER|1|0|0
4|event_type|TEXT|1||0
5|x|INTEGER|0||0
6|y|INTEGER|0||0
7|delta_x|INTEGER|0||0
8|delta_y|INTEGER|0||0
9|button|INTEGER|0||0
10|click_count|INTEGER|0||0
11|key_code|INTEGER|0||0
12|modifiers|INTEGER|0||0
13|text_content|TEXT|0||0
14|text_length|INTEGER|0||0
15|app_name|TEXT|0||0
16|app_pid|INTEGER|0||0
17|window_title|TEXT|0||0
18|browser_url|TEXT|0||0
19|element_role|TEXT|0||0
20|element_name|TEXT|0||0
21|element_value|TEXT|0||0
22|element_description|TEXT|0||0
23|element_automation_id|TEXT|0||0
24|element_bounds|TEXT|0||0
25|frame_id|INTEGER|0||0
26|sync_id|TEXT|0||0
27|machine_id|TEXT|0||0
28|synced_at|DATETIME|0||0
0|id|INTEGER|0||1
1|file_path|TEXT|1||0
2|device_name|TEXT|1|''|0
3|sync_id|TEXT|0||0
4|machine_id|TEXT|0||0
5|synced_at|DATETIME|0||0
6|fps|REAL|1|0.5|0
7|cloud_blob_id|TEXT|0|NULL|0
[rerun: b6]
Bash
Check data counts and date ranges
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM frames;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM audio_transcriptions;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*) FROM ocr_text;" 2>/dev/null
Copy code to clipboard
OUT
1135|2026-04-09T16:53:09.043761+00:00|2026-04-11T12:54:42.597794+00:00
3|2026-04-09T16:53:20+00:00|2026-04-09T17:02:52+00:00
666
[rerun: b7]
Bash
Explore existing pipes for patterns
IN
ls /volume1/screenpipe/pipes/day-recap/ 2>/dev/null && cat /volume1/screenpipe/pipes/day-recap/*.js 2>/dev/null | head -50
Copy code to clipboard
OUT
pipe.md
[rerun: b8]
Bash
Read day-recap pipe documentation
IN
cat /volume1/screenpipe/pipes/day-recap/pipe.md
Copy code to clipboard
OUT
---
schedule: manual
enabled: true
template: true
title: Day Recap
description: "Today's accomplishments, key moments, and unfinished work"
icon: "📋"
featured: true
---
Analyze my screen and audio recordings from today (last 16 hours only).
Read screenpipe skill first.
Use this exact format:
## Summary
One sentence: what I mainly did today.
## Accomplishments
- Top 3 things I finished, with timestamps (e.g. "2:30 PM")
- Name specific apps, files, or projects
## Key Moments
- Important things I saw, said, or heard — with timestamps
## Unfinished Work
- What I should continue tomorrow — name the app/file/task
## Patterns
- Apps I used most, topics that came up repeatedly
Only report what you can verify from the data. End with: "**Next step:** [most important thing to continue]"
[rerun: b9]
Bash
Sample app names from frames
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT DISTINCT app_name FROM frames WHERE app_name != '' LIMIT 20;"
Copy code to clipboard
OUT
Safari
Activity Monitor
Dia
iTerm2
Control Centre
UserNotificationCenter
Finder
Claude
Slack
Firefox
Raycast
NetAuthAgent
QuickTime Player
[rerun: b10]
Bash
Sample joined frame+ocr data for today
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT f.timestamp, o.app_name, o.window_name, substr(o.text, 1, 100) as text FROM frames f JOIN ocr_text o ON f.id = o.frame_id WHERE DATE(f.timestamp) = '2026-04-11' LIMIT 5;"
Copy code to clipboard
OUT
2026-04-11T11:53:00.627698+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <47H5Sat 11 Apr 14:53:00-zshDOCKE
2026-04-11T11:53:02.005967+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <7H5Sat 11 Apr 14:53:01-zshDOCKER
2026-04-11T11:53:03.627468+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:03-zshDOCKERuse p
2026-04-11T11:53:05.528794+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:05-zshDOCKERuse p
2026-04-11T11:53:07.662098+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <7Sat 11 Apr 14:53:07-zshDOCKERuse pi
[rerun: b11]
Bash
Sample recent audio transcriptions
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT timestamp, substr(transcription,1,100) as text, device FROM audio_transcriptions ORDER BY timestamp DESC LIMIT 5;"
Copy code to clipboard
OUT
2026-04-09T17:02:52+00:00|.|System Audio
2026-04-09T16:59:22+00:00|Class is technically...|System Audio
2026-04-09T16:53:20+00:00|I do for you. Run the credit check. Deal apartment. Okay.|System Audio
[rerun: b12]
Thinking
Thinking
Good data to work with. Here's what we have:
frames
+
ocr_text
: Screen captures with OCR text, app name, window name (1135 frames so far)
audio_transcriptions
: Voice/system audio transcripts
ui_events
: Mouse/keyboard events with app context
video_chunks
: Raw video files
Before I start building, a few quick questions:
Tech stack
— Python OK? (FastAPI for the web UI backend, Click for CLI commands, HTMX for the frontend to keep it simple)
AI summaries
— Do you have a Claude API key to use for generating the actual summaries? Or should I integrate with a local model / skip AI for now?
What summaries matter most?
Day recap (what apps/windows you used, key text seen)
App time breakdown (time per app)
Audio/conversation recap
Custom searchable timeline
Here's the architecture I'm thinking:
Copy code to clipboard
/volume1/screenpipe/app/
├── main.py # FastAPI web UI
├── cli.py # Click CLI: `python cli.py day-recap`
├── db.py # Read-only queries against db.sqlite
├── consumers/
│ ├── activity.py # App usage, time per window
│ ├── ocr.py # OCR text aggregation + search
│ ├── audio.py # Transcription queries
│ └── summary.py # AI summary builder
└── static/
└── index.html # Single-page UI
CLI commands would look like:
Copy code to clipboard
python cli.py day-recap # EOD summary
python cli.py activity --date today # App time breakdown
python cli.py search "docker" # Search OCR/audio text
python cli.py serve # Launch web UI
Does this direction work? Any preferences on the stack or which summaries to prioritize?
Message actions
seesm ok
Thinking
Thinking
Bash
Check Python and available packages
IN
python3 --version && pip3 list 2>/dev/null | grep -E "fastapi|uvicorn|click|anthropic|httpx|jinja"
Copy code to clipboard
OUT
Python 3.11.2
[rerun: b1]
Bash
Verify join works for today's data
IN
sqlite3 /volume1/screenpipe/db.sqlite "
SELECT f.timestamp, o.app_name, o.window_name, length(o.text) as txt_len
FROM frames f JOIN ocr_text o ON f.id = o.frame_id
WHERE DATE(f.timestamp) = '2026-04-11'
ORDER BY f.timestamp DESC LIMIT 3;
"
Copy code to clipboard
OUT
2026-04-11T12:54:42.597794+00:00|||2111
2026-04-11T12:54:41.915916+00:00|||2110
2026-04-11T12:54:39.912712+00:00|||2111
[rerun: b2]
Bash
Install required packages
IN
pip3 install fastapi uvicorn click anthropic python-dotenv 2>&1 | tail -5
Copy code to clipboard
OUT
/bin/bash: line 1: pip3: command not found
[rerun: b3]
Bash
Find pip
IN
which pip || which pip3 || python3 -m pip --version 2>/dev/null...
|
Code
|
Build screenpipe data UI… — screenpipe [SSH: 100.7 Build screenpipe data UI… — screenpipe [SSH: 100.73.206.126]...
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpall100% <7-zshDOCKERdeepgram keylanguages• 881DEV (-zsh)not setall languagesО ₴2APP (-zsh)• хз-zsh• x4|-zsh• ₴5|-zsh886-zshO 87Sat 11 Apr 20:28:31-zshT81• *8|monitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry isenabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.3487547ZINFO screenpipe: starting UI event capture2026-04-11T20:26:05.353656ZWARNscreenpipe: pi agent install failed: bun not found - install from https://bun.sh2026-04-11T20:26:05.358540ZINFO2026-04-11T20:26:05.363864Zscreenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.378325ZINFO screenpipe_engine::ui_recorder: Starting UI event captureINFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB(2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFO2026-04-11T20:26:051.384798ZINFOscreenpipe_engine::meeting_detector: meeting V2: detection loop started (base_interval=5s, profiles=12)screenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe onport 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting visionrecordingfor monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFO2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed listscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)2026-04-11T20:26:07.067446ZINFO2026-04-11T20:26:08.752985ZINFOscreenpipe-engine::eventdriven.capture: Sonteut dedup: skipping copture for monitoo 1 (hrs -9215443531147982392, triggeravisualchange)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: localretention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)2026-04-11T20:26:55.992688ZINFO2026-04-11T20:26:57.331771ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:27:05408691ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)screenpipe_engine::snapshot_compaction: snapshot compaction: found 61eligible frames2026-04-11T20:27:09.664908ZINFOscreenpipe_engine::snapshot_compaction: snapshot compaction: 61 frames, 9.4MB 3.3MB (2.8x), 61 JPEGs deleted...
|
NULL
|
NULL
|
NULL
|
|
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update, 1 requires restart
3
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
SCREENPIPE [SSH: [IP_ADDRESS]]
#recycle
app
consumers
__init__.py
activity.py
audio.py
ocr.py
report.py
summary.py
static
.env
cli.py
db.py
docker-compose.yml
Dockerfile
main.py
requirements.txt
data
pipes
db.sqlite
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
pipe.md, Editor Group 1
#!/bin/bash • Untitled-1, Editor Group 1
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
#!/bin/bash
DB="/volume1/Test/screenpipe/db.sqlite"
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "═══════════════════════════════════════"
echo " SCREENPIPE REPORT — $DATE"
echo "═══════════════════════════════════════"
echo -e "\n📱 APP USAGE (frames + estimated time)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-30s %5d frames ~%5.1f min', app_name, COUNT(*), ROUND(COUNT(*) * 4.5 / 60.0, 1))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n⌨️ ACTIVITY TYPE PER APP"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-25s clicks:%-5d keys:%-5d switches:%-4d',
app_name,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='key' THEN 1 ELSE 0 END),
SUM(CASE WHEN event_type='app_switch' THEN 1 ELSE 0 END))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY app_name ORDER BY COUNT(*) DESC;"
echo -e "\n🌐 BROWSER URLS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%4d frames %s', COUNT(*), browser_url)
FROM frames
WHERE date(timestamp) = '$DATE' AND browser_url IS NOT NULL
GROUP BY browser_url ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🪟 WINDOW TITLES (top 20)"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %3d %s', app_name, COUNT(*), SUBSTR(window_name,1,60))
FROM frames
WHERE date(timestamp) = '$DATE' AND window_name IS NOT NULL AND app_name IS NOT NULL
GROUP BY app_name, window_name ORDER BY COUNT(*) DESC LIMIT 20;"
echo -e "\n🕐 HOURLY TIMELINE"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%s %-20s %3d frames', strftime('%H:00', timestamp), app_name, COUNT(*))
FROM frames
WHERE date(timestamp) = '$DATE' AND app_name IS NOT NULL
GROUP BY strftime('%H', timestamp), app_name
ORDER BY strftime('%H', timestamp), COUNT(*) DESC;"
echo -e "\n📋 CLIPBOARD"
echo "───────────────────────────────────────"
sqlite3 "$DB" "
SELECT printf('%-20s %s', app_name, SUBSTR(text_content, 1, 80))
FROM ui_events
WHERE date(timestamp) = '$DATE' AND event_type = 'clipboard' AND text_content IS NOT NULL
ORDER BY timestamp LIMIT 20;"
echo -e "\n🔢 TOTALS"
echo "───────────────────────────────────────"
sqlite3 "$DB" "SELECT 'Frames: ' || COUNT(*) FROM frames WHERE date(timestamp) = '$DATE';"
sqlite3 "$DB" "SELECT 'UI Events: ' || COUNT(*) FROM ui_events WHERE date(timestamp) = '$DATE';"
Build screenpipe data UI…, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: [IP_ADDRESS]
SSH: [IP_ADDRESS]
No Problems
0
0
No Ports Forwarded
0
Update is ready, click to restart.
Update is ready, click to restart.
Notifications
Sign In
Sign In
Screen Reader Optimized
expanded
Build screenpipe data UI and summary app
Session history
New session
Message actions
lets build app around screenpipe data and db. THe idea is to have ui and data consumers. So I can run regular commands at the end ot the day (or on demand) and create soem summary.
Thinking
Thinking
Let me explore the screenpipe directory to understand what we're working with.
Bash
List screenpipe directory contents
IN
ls /volume1/screenpipe/
Copy code to clipboard
OUT
data
db.sqlite
pipes
#recycle
[rerun: b1]
Bash
List data and pipes directories
IN
ls /volume1/screenpipe/data/ | head -20 && ls /volume1/screenpipe/pipes/
Copy code to clipboard
OUT
2026-04-09
2026-04-11
ai-habits
day-recap
meeting-summary
standup-update
time-breakdown
video-export
[rerun: b2]
Bash
List tables in screenpipe SQLite database
IN
sqlite3 /volume1/screenpipe/db.sqlite ".tables"
Copy code to clipboard
OUT
_sqlx_migrations meetings
audio_chunks memories
audio_tags memories_fts
audio_transcriptions memories_fts_config
audio_transcriptions_fts memories_fts_data
audio_transcriptions_fts_config memories_fts_docsize
audio_transcriptions_fts_data memories_fts_idx
audio_transcriptions_fts_docsize ocr_text
audio_transcriptions_fts_idx pipe_executions
elements pipe_scheduler_state
elements_fts speaker_embeddings
elements_fts_config speakers
elements_fts_data tags
elements_fts_docsize ui_events
elements_fts_idx ui_events_fts
frames ui_events_fts_config
frames_fts ui_events_fts_data
frames_fts_config ui_events_fts_docsize
frames_fts_content ui_events_fts_idx
frames_fts_data video_chunks
frames_fts_docsize vision_tags
frames_fts_idx
[rerun: b3]
Bash
Get ocr_text table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(ocr_text);"
Copy code to clipboard
OUT
0|frame_id|INTEGER|1||0
1|text|TEXT|1||0
2|text_json|TEXT|0||0
3|app_name|TEXT|1|''|0
4|ocr_engine|TEXT|1|'unknown'|0
5|window_name|TEXT|0||0
6|focused|BOOLEAN|0|FALSE|0
7|text_length|INTEGER|0||0
8|sync_id|TEXT|0||0
9|synced_at|DATETIME|0||0
[rerun: b4]
Bash
Get audio_transcriptions table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(audio_transcriptions);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|audio_chunk_id|INTEGER|1||0
2|offset_index|INTEGER|1||0
3|timestamp|TIMESTAMP|1||0
4|transcription|TEXT|1||0
5|device|TEXT|1|''|0
6|is_input_device|BOOLEAN|1|TRUE|0
7|speaker_id|INTEGER|0||0
8|transcription_engine|TEXT|1|'Whisper'|0
9|start_time|REAL|0||0
10|end_time|REAL|0||0
11|text_length|INTEGER|0||0
12|sync_id|TEXT|0||0
13|synced_at|DATETIME|0||0
[rerun: b5]
Bash
Get frames, ui_events, video_chunks schemas
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(frames); PRAGMA table_info(ui_events); PRAGMA table_info(video_chunks);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|video_chunk_id|INTEGER|0|NULL|0
2|offset_index|INTEGER|1|0|0
3|timestamp|TIMESTAMP|1||0
4|name|TEXT|0||0
5|app_name|TEXT|0|NULL|0
6|window_name|TEXT|0|NULL|0
7|focused|BOOLEAN|0|NULL|0
8|browser_url|TEXT|0|NULL|0
9|device_name|TEXT|1|''|0
10|sync_id|TEXT|0||0
11|machine_id|TEXT|0||0
12|synced_at|DATETIME|0||0
13|snapshot_path|TEXT|0|NULL|0
14|accessibility_text|TEXT|0|NULL|0
15|accessibility_tree_json|TEXT|0|NULL|0
16|content_hash|INTEGER|0|NULL|0
17|simhash|INTEGER|0|NULL|0
18|capture_trigger|TEXT|0|NULL|0
19|text_source|TEXT|0|NULL|0
20|cloud_blob_id|TEXT|0|NULL|0
21|full_text|TEXT|0|NULL|0
22|elements_ref_frame_id|INTEGER|0|NULL|0
0|id|INTEGER|0||1
1|timestamp|DATETIME|1|CURRENT_TIMESTAMP|0
2|session_id|TEXT|0||0
3|relative_ms|INTEGER|1|0|0
4|event_type|TEXT|1||0
5|x|INTEGER|0||0
6|y|INTEGER|0||0
7|delta_x|INTEGER|0||0
8|delta_y|INTEGER|0||0
9|button|INTEGER|0||0
10|click_count|INTEGER|0||0
11|key_code|INTEGER|0||0
12|modifiers|INTEGER|0||0
13|text_content|TEXT|0||0
14|text_length|INTEGER|0||0
15|app_name|TEXT|0||0
16|app_pid|INTEGER|0||0
17|window_title|TEXT|0||0
18|browser_url|TEXT|0||0
19|element_role|TEXT|0||0
20|element_name|TEXT|0||0
21|element_value|TEXT|0||0
22|element_description|TEXT|0||0
23|element_automation_id|TEXT|0||0
24|element_bounds|TEXT|0||0
25|frame_id|INTEGER|0||0
26|sync_id|TEXT|0||0
27|machine_id|TEXT|0||0
28|synced_at|DATETIME|0||0
0|id|INTEGER|0||1
1|file_path|TEXT|1||0
2|device_name|TEXT|1|''|0
3|sync_id|TEXT|0||0
4|machine_id|TEXT|0||0
5|synced_at|DATETIME|0||0
6|fps|REAL|1|0.5|0
7|cloud_blob_id|TEXT|0|NULL|0
[rerun: b6]
Bash
Check data counts and date ranges
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM frames;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM audio_transcriptions;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*) FROM ocr_text;" 2>/dev/null
Copy code to clipboard
OUT
1135|2026-04-09T16:53:09.043761+00:00|2026-04-11T12:54:42.597794+00:00
3|2026-04-09T16:53:20+00:00|2026-04-09T17:02:52+00:00
666
[rerun: b7]
Bash
Explore existing pipes for patterns
IN
ls /volume1/screenpipe/pipes/day-recap/ 2>/dev/null && cat /volume1/screenpipe/pipes/day-recap/*.js 2>/dev/null | head -50
Copy code to clipboard
OUT
pipe.md
[rerun: b8]
Bash
Read day-recap pipe documentation
IN
cat /volume1/screenpipe/pipes/day-recap/pipe.md
Copy code to clipboard
OUT
---
schedule: manual
enabled: true
template: true
title: Day Recap
description: "Today's accomplishments, key moments, and unfinished work"
icon: "📋"
featured: true
---
Analyze my screen and audio recordings from today (last 16 hours only).
Read screenpipe skill first.
Use this exact format:
## Summary
One sentence: what I mainly did today.
## Accomplishments
- Top 3 things I finished, with timestamps (e.g. "2:30 PM")
- Name specific apps, files, or projects
## Key Moments
- Important things I saw, said, or heard — with timestamps
## Unfinished Work
- What I should continue tomorrow — name the app/file/task
## Patterns
- Apps I used most, topics that came up repeatedly
Only report what you can verify from the data. End with: "**Next step:** [most important thing to continue]"
[rerun: b9]
Bash
Sample app names from frames
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT DISTINCT app_name FROM frames WHERE app_name != '' LIMIT 20;"
Copy code to clipboard
OUT
Safari
Activity Monitor
Dia
iTerm2
Control Centre
UserNotificationCenter
Finder
Claude
Slack
Firefox
Raycast
NetAuthAgent
QuickTime Player
[rerun: b10]
Bash
Sample joined frame+ocr data for today
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT f.timestamp, o.app_name, o.window_name, substr(o.text, 1, 100) as text FROM frames f JOIN ocr_text o ON f.id = o.frame_id WHERE DATE(f.timestamp) = '2026-04-11' LIMIT 5;"
Copy code to clipboard
OUT
2026-04-11T11:53:00.627698+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <47H5Sat 11 Apr 14:53:00-zshDOCKE
2026-04-11T11:53:02.005967+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <7H5Sat 11 Apr 14:53:01-zshDOCKER
2026-04-11T11:53:03.627468+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:03-zshDOCKERuse p
2026-04-11T11:53:05.528794+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:05-zshDOCKERuse p
2026-04-11T11:53:07.662098+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <7Sat 11 Apr 14:53:07-zshDOCKERuse pi
[rerun: b11]
Bash
Sample recent audio transcriptions
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT timestamp, substr(transcription,1,100) as text, device FROM audio_transcriptions ORDER BY timestamp DESC LIMIT 5;"
Copy code to clipboard
OUT
2026-04-09T17:02:52+00:00|.|System Audio
2026-04-09T16:59:22+00:00|Class is technically...|System Audio
2026-04-09T16:53:20+00:00|I do for you. Run the credit check. Deal apartment. Okay.|System Audio
[rerun: b12]
Thinking
Thinking
Good data to work with. Here's what we have:
frames
+
ocr_text
: Screen captures with OCR text, app name, window name (1135 frames so far)
audio_transcriptions
: Voice/system audio transcripts
ui_events
: Mouse/keyboard events with app context
video_chunks
: Raw video files
Before I start building, a few quick questions:
Tech stack
— Python OK? (FastAPI for the web UI backend, Click for CLI commands, HTMX for the frontend to keep it simple)
AI summaries
— Do you have a Claude API key to use for generating the actual summaries? Or should I integrate with a local model / skip AI for now?
What summaries matter most?
Day recap (what apps/windows you used, key text seen)
App time breakdown (time per app)
Audio/conversation recap
Custom searchable timeline
Here's the architecture I'm thinking:
Copy code to clipboard
/volume1/screenpipe/app/
├── main.py # FastAPI web UI
├── cli.py # Click CLI: `python cli.py day-recap`
├── db.py # Read-only queries against db.sqlite
├── consumers/
│ ├── activity.py # App usage, time per window
│ ├── ocr.py # OCR text aggregation + search
│ ├── audio.py # Transcription queries
│ └── summary.py # AI summary builder
└── static/
└── index.html # Single-page UI
CLI commands would look like:
Copy code to clipboard
python cli.py day-recap # EOD summary
python cli.py activity --date today # App time breakdown
python cli.py search "docker" # Search OCR/audio text
python cli.py serve # Launch web UI
Does this direction work? Any preferences on the stack or which summaries to prioritize?
Message actions
seesm ok
Thinking...
|
Code
|
Build screenpipe data UI… — screenpipe [SSH: 100.7 Build screenpipe data UI… — screenpipe [SSH: 100.73.206.126]...
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpall-zshDOCKERdeepgram keylanguages• 881DEV (-zsh)not setall languagesО ₴2APP (-zsh)• хз-zsh• x4|-zsh• ₴5|-zsh886-zsh100% <7O 87Sat 11 Apr 20:28:37-zshT81• *8monitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry isenabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.3487547ZINFO screenpipe: starting UI event capture2026-04-11T20:26:05.353656ZWARNscreenpipe: pi agent install failed: bun not found - install from https://bun.sh2026-04-11T20:26:05.358540ZINFO2026-04-11T20:26:05.363864Zscreenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.378325ZINFO screenpipe_engine::ui_recorder: Starting UI event captureINFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB(2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFO2026-04-11T20:26:051.384798ZINFOscreenpipe_engine::meeting_detector: meeting V2: detection loop started (base_interval=5s, profiles=12)screenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe onport 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting visionrecordingfor monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFO2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed listscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)2026-04-11T20:26:07.067446ZINFO2026-04-11T20:26:08.752985ZINFOscreenpipe-engine::eventdriven.capture: Sonteut dedup: skipping copture for monitoo 1 (hrs -9215443531147982392, triggeravisualchange)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: localretention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)2026-04-11T20:26:55.992688ZINFO2026-04-11T20:26:57.331771ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:27:05408691ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)screenpipe_engine::snapshot_compaction: snapshot compaction: found 61eligible frames2026-04-11T20:27:09.664908ZINFOscreenpipe_engine::snapshot_compaction: snapshot compaction: 61 frames, 9.4MB 3.3MB (2.8x), 61 JPEGs deleted...
|
NULL
|
NULL
|
NULL
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(ahl-zshDOCKERdeepgram keylanguages• 881DEV (-zsh)not setall languagesО ₴2APP (-zsh)• *3-zsh• x4|-zsh• ₴5|-zsh886-zsh100% <7O 87Sat 11 Apr 20:28:40-zsh181• *8monitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry isenabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.3487547ZINFO screenpipe: starting UI event capture2026-04-11T20:26:05.353656ZWARNscreenpipe: pi agent install failed: bun not found - install from https://bun.sh2026-04-11T20:26:05.358540ZINFO2026-04-11T20:26:05.363864Zscreenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.378325ZINFO screenpipe_engine::ui_recorder: Starting UI event captureINFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB(2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFO2026-04-11T20:26:051.384798ZINFOscreenpipe_engine::meeting_detector: meeting V2: detection loop started (base_interval=5s, profiles=12)screenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe onport 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting visionrecordingfor monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFO2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed listscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)2026-04-11T20:26:07.067446ZINFO2026-04-11T20:26:08.752985ZINFOscreenpipe-engine::eventdriven.capture: Sonteut dedup: skipping copture for monitoo 1 (hrs -9215443531147982392, triggeravisualchange)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: localretention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)2026-04-11T20:26:55.992688ZINFO2026-04-11T20:26:57.331771ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:27:05408691ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)screenpipe_engine::snapshot_compaction: snapshot compaction: found 61eligible frames2026-04-11T20:27:09.664908ZINFOscreenpipe_engine::snapshot_compaction: snapshot compaction: 61 frames, 9.4MB 3.3MB (2.8x), 61 JPEGs deleted...
|
NULL
|
NULL
|
NULL
|
|
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Explorer (⇧⌘E) - 1 unsaved file
1
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update, 1 requires restart
3
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
Explorer Section: screenpipe [SSH: [IP_ADDRESS]]
SCREENPIPE [SSH: [IP_ADDRESS]]
#recycle
app
consumers
__init__.py
activity.py
audio.py
ocr.py
report.py
summary.py
static
.env
cli.py
db.py
docker-compose.yml
Dockerfile
main.py
requirements.txt
data
pipes
db.sqlite
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
pipe.md, Editor Group 1
#!/bin/bash • Untitled-1, Editor Group 1
report.py, preview, Editor Group 1
report.py, preview, Editor Group 1
Build screenpipe data UI…, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: [IP_ADDRESS]
SSH: [IP_ADDRESS]
No Problems
0
0
No Ports Forwarded
0
Update is ready, click to restart.
Update is ready, click to restart.
Notifications
Sign In
Sign In
Screen Reader Optimized
expanded
Build screenpipe data UI and summary app
Session history
New session
Message actions
lets build app around screenpipe data and db. THe idea is to have ui and data consumers. So I can run regular commands at the end ot the day (or on demand) and create soem summary.
Thinking
Thinking
Let me explore the screenpipe directory to understand what we're working with.
Bash
List screenpipe directory contents
IN
ls /volume1/screenpipe/
Copy code to clipboard
OUT
data
db.sqlite
pipes
#recycle
[rerun: b1]
Bash
List data and pipes directories
IN
ls /volume1/screenpipe/data/ | head -20 && ls /volume1/screenpipe/pipes/
Copy code to clipboard
OUT
2026-04-09
2026-04-11
ai-habits
day-recap
meeting-summary
standup-update
time-breakdown
video-export
[rerun: b2]
Bash
List tables in screenpipe SQLite database
IN
sqlite3 /volume1/screenpipe/db.sqlite ".tables"
Copy code to clipboard
OUT
_sqlx_migrations meetings
audio_chunks memories
audio_tags memories_fts
audio_transcriptions memories_fts_config
audio_transcriptions_fts memories_fts_data
audio_transcriptions_fts_config memories_fts_docsize
audio_transcriptions_fts_data memories_fts_idx
audio_transcriptions_fts_docsize ocr_text
audio_transcriptions_fts_idx pipe_executions
elements pipe_scheduler_state
elements_fts speaker_embeddings
elements_fts_config speakers
elements_fts_data tags
elements_fts_docsize ui_events
elements_fts_idx ui_events_fts
frames ui_events_fts_config
frames_fts ui_events_fts_data
frames_fts_config ui_events_fts_docsize
frames_fts_content ui_events_fts_idx
frames_fts_data video_chunks
frames_fts_docsize vision_tags
frames_fts_idx
[rerun: b3]
Bash
Get ocr_text table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(ocr_text);"
Copy code to clipboard
OUT
0|frame_id|INTEGER|1||0
1|text|TEXT|1||0
2|text_json|TEXT|0||0
3|app_name|TEXT|1|''|0
4|ocr_engine|TEXT|1|'unknown'|0
5|window_name|TEXT|0||0
6|focused|BOOLEAN|0|FALSE|0
7|text_length|INTEGER|0||0
8|sync_id|TEXT|0||0
9|synced_at|DATETIME|0||0
[rerun: b4]
Bash
Get audio_transcriptions table schema
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(audio_transcriptions);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|audio_chunk_id|INTEGER|1||0
2|offset_index|INTEGER|1||0
3|timestamp|TIMESTAMP|1||0
4|transcription|TEXT|1||0
5|device|TEXT|1|''|0
6|is_input_device|BOOLEAN|1|TRUE|0
7|speaker_id|INTEGER|0||0
8|transcription_engine|TEXT|1|'Whisper'|0
9|start_time|REAL|0||0
10|end_time|REAL|0||0
11|text_length|INTEGER|0||0
12|sync_id|TEXT|0||0
13|synced_at|DATETIME|0||0
[rerun: b5]
Bash
Get frames, ui_events, video_chunks schemas
IN
sqlite3 /volume1/screenpipe/db.sqlite "PRAGMA table_info(frames); PRAGMA table_info(ui_events); PRAGMA table_info(video_chunks);"
Copy code to clipboard
OUT
0|id|INTEGER|0||1
1|video_chunk_id|INTEGER|0|NULL|0
2|offset_index|INTEGER|1|0|0
3|timestamp|TIMESTAMP|1||0
4|name|TEXT|0||0
5|app_name|TEXT|0|NULL|0
6|window_name|TEXT|0|NULL|0
7|focused|BOOLEAN|0|NULL|0
8|browser_url|TEXT|0|NULL|0
9|device_name|TEXT|1|''|0
10|sync_id|TEXT|0||0
11|machine_id|TEXT|0||0
12|synced_at|DATETIME|0||0
13|snapshot_path|TEXT|0|NULL|0
14|accessibility_text|TEXT|0|NULL|0
15|accessibility_tree_json|TEXT|0|NULL|0
16|content_hash|INTEGER|0|NULL|0
17|simhash|INTEGER|0|NULL|0
18|capture_trigger|TEXT|0|NULL|0
19|text_source|TEXT|0|NULL|0
20|cloud_blob_id|TEXT|0|NULL|0
21|full_text|TEXT|0|NULL|0
22|elements_ref_frame_id|INTEGER|0|NULL|0
0|id|INTEGER|0||1
1|timestamp|DATETIME|1|CURRENT_TIMESTAMP|0
2|session_id|TEXT|0||0
3|relative_ms|INTEGER|1|0|0
4|event_type|TEXT|1||0
5|x|INTEGER|0||0
6|y|INTEGER|0||0
7|delta_x|INTEGER|0||0
8|delta_y|INTEGER|0||0
9|button|INTEGER|0||0
10|click_count|INTEGER|0||0
11|key_code|INTEGER|0||0
12|modifiers|INTEGER|0||0
13|text_content|TEXT|0||0
14|text_length|INTEGER|0||0
15|app_name|TEXT|0||0
16|app_pid|INTEGER|0||0
17|window_title|TEXT|0||0
18|browser_url|TEXT|0||0
19|element_role|TEXT|0||0
20|element_name|TEXT|0||0
21|element_value|TEXT|0||0
22|element_description|TEXT|0||0
23|element_automation_id|TEXT|0||0
24|element_bounds|TEXT|0||0
25|frame_id|INTEGER|0||0
26|sync_id|TEXT|0||0
27|machine_id|TEXT|0||0
28|synced_at|DATETIME|0||0
0|id|INTEGER|0||1
1|file_path|TEXT|1||0
2|device_name|TEXT|1|''|0
3|sync_id|TEXT|0||0
4|machine_id|TEXT|0||0
5|synced_at|DATETIME|0||0
6|fps|REAL|1|0.5|0
7|cloud_blob_id|TEXT|0|NULL|0
[rerun: b6]
Bash
Check data counts and date ranges
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM frames;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*), MIN(timestamp), MAX(timestamp) FROM audio_transcriptions;" 2>/dev/null
sqlite3 /volume1/screenpipe/db.sqlite "SELECT COUNT(*) FROM ocr_text;" 2>/dev/null
Copy code to clipboard
OUT
1135|2026-04-09T16:53:09.043761+00:00|2026-04-11T12:54:42.597794+00:00
3|2026-04-09T16:53:20+00:00|2026-04-09T17:02:52+00:00
666
[rerun: b7]
Bash
Explore existing pipes for patterns
IN
ls /volume1/screenpipe/pipes/day-recap/ 2>/dev/null && cat /volume1/screenpipe/pipes/day-recap/*.js 2>/dev/null | head -50
Copy code to clipboard
OUT
pipe.md
[rerun: b8]
Bash
Read day-recap pipe documentation
IN
cat /volume1/screenpipe/pipes/day-recap/pipe.md
Copy code to clipboard
OUT
---
schedule: manual
enabled: true
template: true
title: Day Recap
description: "Today's accomplishments, key moments, and unfinished work"
icon: "📋"
featured: true
---
Analyze my screen and audio recordings from today (last 16 hours only).
Read screenpipe skill first.
Use this exact format:
## Summary
One sentence: what I mainly did today.
## Accomplishments
- Top 3 things I finished, with timestamps (e.g. "2:30 PM")
- Name specific apps, files, or projects
## Key Moments
- Important things I saw, said, or heard — with timestamps
## Unfinished Work
- What I should continue tomorrow — name the app/file/task
## Patterns
- Apps I used most, topics that came up repeatedly
Only report what you can verify from the data. End with: "**Next step:** [most important thing to continue]"
[rerun: b9]
Bash
Sample app names from frames
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT DISTINCT app_name FROM frames WHERE app_name != '' LIMIT 20;"
Copy code to clipboard
OUT
Safari
Activity Monitor
Dia
iTerm2
Control Centre
UserNotificationCenter
Finder
Claude
Slack
Firefox
Raycast
NetAuthAgent
QuickTime Player
[rerun: b10]
Bash
Sample joined frame+ocr data for today
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT f.timestamp, o.app_name, o.window_name, substr(o.text, 1, 100) as text FROM frames f JOIN ocr_text o ON f.id = o.frame_id WHERE DATE(f.timestamp) = '2026-04-11' LIMIT 5;"
Copy code to clipboard
OUT
2026-04-11T11:53:00.627698+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <47H5Sat 11 Apr 14:53:00-zshDOCKE
2026-04-11T11:53:02.005967+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA-zsh100% <7H5Sat 11 Apr 14:53:01-zshDOCKER
2026-04-11T11:53:03.627468+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:03-zshDOCKERuse p
2026-04-11T11:53:05.528794+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <47Sat 11 Apr 14:53:05-zshDOCKERuse p
2026-04-11T11:53:07.662098+00:00|||iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0(ahlA100% <7Sat 11 Apr 14:53:07-zshDOCKERuse pi
[rerun: b11]
Bash
Sample recent audio transcriptions
IN
sqlite3 /volume1/screenpipe/db.sqlite "SELECT timestamp, substr(transcription,1,100) as text, device FROM audio_transcriptions ORDER BY timestamp DESC LIMIT 5;"
Copy code to clipboard
OUT
2026-04-09T17:02:52+00:00|.|System Audio
2026-04-09T16:59:22+00:00|Class is technically...|System Audio
2026-04-09T16:53:20+00:00|I do for you. Run the credit check. Deal apartment. Okay.|System Audio
[rerun: b12]
Thinking
Thinking
Good data to work with. Here's what we have:
frames
+
ocr_text
: Screen captures with OCR text, app name, window name (1135 frames so far)
audio_transcriptions
: Voice/system audio transcripts
ui_events
: Mouse/keyboard events with app context
video_chunks
: Raw video files
Before I start building, a few quick questions:
Tech stack
— Python OK? (FastAPI for the web UI backend, Click for CLI commands, HTMX for the frontend to keep it simple)
AI summaries
— Do you have a Claude API key to use for generating the actual summaries? Or should I integrate with a local model / skip AI for now?
What summaries matter most?
Day recap (what apps/windows you used, key text seen)
App time breakdown (time per app)
Audio/conversation recap
Custom searchable timeline
Here's the architecture I'm thinking:
Copy code to clipboard
/volume1/screenpipe/app/
├── main.py # FastAPI web UI
├── cli.py # Click CLI: `python cli.py day-recap`
├── db.py # Read-only queries against db.sqlite
├── consumers/
│ ├── activity.py # App usage, time per window
│ ├── ocr.py # OCR text aggregation + search
│ ├── audio.py # Transcription queries
│ └── summary.py # AI summary builder
└── static/
└── index.html # Single-page UI
CLI commands would look like:
Copy code to clipboard
python cli.py day-recap # EOD summary
python cli.py activity --date today # App time breakdown
python cli.py search "docker" # Search OCR/audio text
python cli.py serve # Launch web UI
Does this direction work? Any preferences on the stack or which summaries to prioritize?
Message actions
seesm ok
Thinking
Thinking
Bash
Check Python and available packages
IN
python3 --version && pip3 list 2>/dev/null | grep -E "fastapi|uvicorn|click|anthropic|httpx|jinja"
Copy code to clipboard
OUT
Python 3.11.2
[rerun: b1]
Bash
Verify join works for today's data
IN
sqlite3 /volume1/screenpipe/db.sqlite "
SELECT f.timestamp, o.app_name, o.window_name, length(o.text) as txt_len
FROM frames f JOIN ocr_text o ON f.id = o.frame_id
WHERE DATE(f.timestamp) = '2026-04-11'
ORDER BY f.timestamp DESC LIMIT 3;
"
Copy code to clipboard
OUT
2026-04-11T12:54:42.597794+00:00|||2111
2026-04-11T12:54:41.915916+00:00|||2110
2026-04-11T12:54:39.912712+00:00|||2111
[rerun: b2]
Bash
Install required packages...
|
Code
|
Build screenpipe data UI… — screenpipe [SSH: 100.7 Build screenpipe data UI… — screenpipe [SSH: 100.73.206.126]...
|
NULL
|
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Irán – Denník N
Irán – Denník N
Vimium Options
Vimium Options
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Search results for "bitwarden" – Add-ons for Firefox (en-US)
Search results for "bitwarden" – Add-ons for Firefox (en-US)
New Tab
New Tab
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Browser Extension Getting Started | Bitwarden
Browser Extension Getting Started | Bitwarden
Extensions – Add-ons for Firefox (en-US)
Extensions – Add-ons for Firefox (en-US)
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
11
/
04
/
2026
Calendar
TOTAL SPAN
1.0h
14:52 → 15:54
ACTIVE
1.0h
BREAKS
0 breaks · 0.0h
SESSIONS
1
62m
FRAMES
612
APPS
6
UI EVENTS
1344
AUDIO
0
ACTIVE PERIOD
14:52 → 15:54
TIME PER APP
— CLICK TO FILTER RIGHT PANEL
iTerm2
5.2m
Firefox
1.5m
Finder
0.6m
QuickTime Player
0.5m
NetAuthAgent
0.1m
Raycast
0.1m
Websites
Windows
UI Events
nas.lakylak.xyz/desktop/#/
0.7m
play.hbomax.com/video/watch/6b742798-e5fa-4f90-8beb-74c328dc5028/65d19c63-e85e-4392-8594-f0f2e0a1dc2d
0.1m
nas.lakylak.xyz/desktop/#/login/account
0.1m
login.tailscale.com/login?next_url=%2Fadmin
0.1m
dennikn.sk/5263377/lod-orion-uspesne-pristala-na-zemi-desat-veci-ktore-si-pamatat-na-misii-artemis-ii/
0.1m
http://localhost:3030
0m
addons.mozilla.org/en-US/firefox/addon/vimium-ff/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0m
accounts.google.com/v3/signin/accountchooser?access_type=offline&client_id=674241127656-lmq9su4p8ni1tcpuh6eqidoornqtvmvi.apps.googleusercontent.com&prompt=select_account&redirect_uri=https%3A%2F%2Flogin.tailscale.com%2Fa%2Foauth_response&response_type=code&scope=openid+email+profile&state=tc-ftYwP8oB0urJfQZeh42KPfA&dsh=S1949714251%3A1775911302074699&o2v=2&service=lso&flowName=GeneralOAuthFlow&opparams=%253F&continue=https%3A%2F%2Faccounts.google.com%2Fsignin%2Foauth%2Fconsent%3Fauthuser%3Dunknown%26part%3DAJi8hAOOoeMJ9h1ZWE-Aau2rWQdjwJ-4Enpv6Ci-0hiDSq5jW9TsVTl1btOELm96_EZaQdgfRwBdj1zZGB_CYauRC0fkTqY_cZ35H_NcJOU2_4Ax0Gtto-fKf-nDgh4daUIBqdTh68bjSxOce25-KnK0XYdHV8mzb69bNhDZHVDj_gb42yLS6CaLOtRfvBqDUDqR3SzLMQPfBkXHhJz6IM_7wq52TLTL563ihzeGQBECsxCnD1Yk27REW5r_eZ0TNXkkAX7P1hB8gAkBKuZVXHltsgP7jvfc8R1fsuXURwjdV8kBOMOg3Reld6-0t5nB9qwgvuYCJsuo0Q7IMz9o-t41651a_Wsc0FnlTxFC_0DA-eKXtSlPZHRy9BW_O_UgliMh8Y9cnLpKZ4r9A_LwCm6flXHR1tZWe_NA_YGhQ9EYSdByTuW1hMcIXXh1Alssc0Sb9BtxZ5mPnlLjTXaWd8LEtCrsHv1HQQ%26flowName%3DGeneralOAuthFlow%26as%3DS1949714251%253A1775911302074699%26client_id%3D674241127656-lmq9su4p8ni1tcpuh6eqidoornqtvmvi.apps.googleusercontent.com%26requestPath%3D%252Fsignin%252Foauth%252Fconsent%23&app_domain=https%3A%2F%2Flogin.tailscale.com
0m...
|
Firefox
|
Screenpipe Dashboard — Personal
|
http://100.73.206.126:8766
|
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelpall100% <7-zshDOCKERdeepgram keylanguages• 881DEV (-zsh)not setall languagesО ₴2APP (-zsh)• хз-zsh• x4|-zsh• ₴5|-zsh886-zshO 87Sat 11 Apr 20:29:18-zsh181• *8|monitorsno monitors availableaudio devicesdisabledyou are using local processing. all your data stays on your computer.warning: telemetry isenabled. only error-level data will be sent.to disable, use the --disable-telemetry flag.check latest changes here: https://github.com/screenpipe/screenpipe/releases2026-04-11T20:26:05.348501ZINFO screenpipe_core::pipes:pipe scheduler started (generation 2)2026-04-11T20:26:05.3487547ZINFO screenpipe: starting UI event capture2026-04-11T20:26:05.353656ZWARNscreenpipe: pi agent install failed: bun not found - install from https://bun.sh2026-04-11T20:26:05.358540ZINFO2026-04-11T20:26:05.363864Zscreenpipe_engine::power::manager: initial power profile: Performance (on_ac=true, battery=Some(100))2026-04-11T20:26:05.378325ZINFO screenpipe_engine::ui_recorder: Starting UI event captureINFO screenpipe_engine::calendar_speaker_id: speaker identification: started (user_name=<not set>)2026-04-11T20:26:05.378392ZINFOscreenpipe_engine::ui_recorder: UI recording session started: 5b17c7fe-3811-4788-a81b-6b04773808f12026-04-11T20:26:05.378564ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmingfrom DB(2026-04-10 17:26:05.378561 UTC to 2026-04-11 17:26:05.378561 UTC)2026-04-11T20:26:05.379467ZINFO2026-04-11T20:26:051.384798ZINFOscreenpipe_engine::meeting_detector: meeting V2: detection loop started (base_interval=5s, profiles=12)screenpipe_engine::server: Server listening on [IP_ADDRESS]:30302026-04-11T20:26:05.389960ZINFOscreenpipe_connect::mdns: mdns: advertising screenpipe onport 30302026-04-11T20:26:05.528107ZINFOscreenpipe_engine::hot_frame_cache: hot_frame_cache: warmed with 883frame entries, coverage from 2026-04-10 17:26:05.378561 UTC2026-04-11T20:26:05.683177ZINFOscreenpipe_engine::vision_manager::manager: Starting visionrecordingfor monitor 1 (1440x900)2026-04-11T20:26:05.683293ZINFOscreenpipe_engine::vision_manager::manager: Starting event-driven capture for monitor 1 (device: monitor_1)2026-04-11T20:26:05.683303ZINFO2026-04-11T20:26:05.683311ZINFOscreenpipe_engine::vision_manager::manager: Skipping monitor 2 (Display 2_2560x1440_-597,-1440) - not in allowed listscreenpipe_engine::vision_manager::monitor_watcher: Starting monitor watcher (polling every 5 seconds)2026-04-11T20:26:05.683359ZINFOscreenpipe_engine::event_driven_capture: event-driven capture started for monitor 1 (device: monitor_1)2026-04-11T20:26:06.488545ZINFOsck_rs::stream_manager: persistent SCK stream started for display 1 (1440x900, 2fps)2026-04-11T20:26:07.067446ZINFO2026-04-11T20:26:08.752985ZINFOscreenpipe-engine::eventdriven.capture: Sonteut dedup: skipping copture for monitoo 1 (hrs -9215443531147982392, triggeravisualchange)2026-04-11T20:26:10.383131ZINFOscreenpipe_engine::retention: retention: initialized with 14d retention2026-04-11T20:26:10.383762ZINFOscreenpipe: localretention auto-enabled (14 days)2026-04-11T20:26:38.337011ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=-9215443531147982391, trigger=click)2026-04-11T20:26:55.992688ZINFO2026-04-11T20:26:57.331771ZINFOscreenpipe_engine::event_driven_capture: content dedup: skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)2026-04-11T20:27:05408691ZINFOscreenpipe_engine::event_driven_capture: content dedup:skipping capture for monitor 1 (hash=5606118560581161138, trigger=click)screenpipe_engine::snapshot_compaction: snapshot compaction: found 61eligible frames2026-04-11T20:27:09.664908ZINFOscreenpipe_engine::snapshot_compaction: snapshot compaction: 61 frames, 9.4MB 3.3MB (2.8x), 61 JPEGs deleted...
|
NULL
|
NULL
|
NULL
|
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Vimium – Get this Extension for 🦊 Firefox (en-US)
Vimium – Get this Extension for 🦊 Firefox (en-US)
Irán – Denník N
Irán – Denník N
Vimium Options
Vimium Options
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Loď Orion úspešne pristála na Zemi. Desať vecí, ktoré si pamätať o misii Artemis II — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Search results for "bitwarden" – Add-ons for Firefox (en-US)
Search results for "bitwarden" – Add-ons for Firefox (en-US)
Close tab
New Tab
New Tab
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Bitwarden Password Manager – Get this Extension for 🦊 Firefox (en-US)
Browser Extension Getting Started | Bitwarden
Browser Extension Getting Started | Bitwarden
Extensions – Add-ons for Firefox (en-US)
Extensions – Add-ons for Firefox (en-US)
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Firefox Browser Add-ons
Firefox Browser Add-ons
Extensions
Extensions
Themes
Themes
More…
More…
Firefox Add-ons Blog
Firefox Add-ons Blog
Extension Workshop
Extension Workshop
Developer Hub
Developer Hub
Log in
Log in
Search
bitwarden
bitwarden
bitwarden
Search
Search
11 results found for "bitwarden"
11 results found for "bitwarden"
Filter results
Filter results
Sort by
Add-on Type
Badging
Search results
Bitwarden Password Manager Recommended Recommended
Bitwarden Password Manager
Bitwarden Password Manager
Recommended Recommended
Recommended
Recommended
At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.
Rated 4.6 out of 5
Bitwarden Inc.
Bitwarden Inc.
965,377 users
965,377 users
Scout Vault
Scout Vault
Scout Vault
At home, at work, or on the go, Scout Vault easily secures all your passwords, passkeys, and sensitive information
There are no ratings yet
Scout Secured
Scout Secured
4 users
4 users
Sunsetvault
Sunsetvault
Sunsetvault
Sunsetvault is an exclusive build of the popular open source password manager, designed for internal use by SETG.
Rated 5 out of 5
Sunset
Sunset
12 users
12 users
Twake Pass
Twake Pass
Twake Pass
Twake Pass, the French and open source password manager application of your Twake Workplace that makes you the Internet easier by helping you to create, save and autofill strong passwords for all your accounts so you can browse securely online.
Rated 4.7 out of 5
Twake Workplace
Twake Workplace
1,045 users
1,045 users
Heimlane Vault
Heimlane Vault
Heimlane Vault
Password manager extension that securely stores, manages, and auto-fills login credentials for websites. Provides password generation and secure sharing capabilities.
There are no ratings yet
Heimlane
Heimlane
15 users
15 users
SAASPASS Password Manager & Authenticator 2FA SSO
SAASPASS Password Manager & Authenticator 2FA SSO
SAASPASS Password Manager & Authenticator 2FA SSO
SAASPASS is a free Password Manager & Authenticator [BACKUP_CODE]. There is NO need for a desktop application. You can use the Authenticator code generator & SAASPASS can autofill & autologin as well with single sign-on SSO
Rated 4.2 out of 5
SAASPASS
SAASPASS
260 users
260 users
Password Autofill Defocus
Password Autofill Defocus
Password Autofill Defocus
Defocuses password fields after auto-fill on HTTP pages, preventing Firefox's insecure login warning from blocking the login button.
There are no ratings yet
Nealon
Nealon
2 users
2 users
Authier
Authier
Authier
Authier chrome extension
There are no ratings yet
capaj
capaj
16 users
16 users
idrinth/walled-secrets
idrinth/walled-secrets
idrinth/walled-secrets
A small open source password manager.
Rated 5 out of 5
Björn 'Idrinth' Büttner
Björn 'Idrinth' Büttner
1 user
1 user
VivoKey Vault
VivoKey Vault
VivoKey Vault
A secure password manager, backed by the VivoKey Cryptobionic Identity.
There are no ratings yet
Riley Gall
Riley Gall
2 users
2 users
Overconfidence Password Generator
Overconfidence Password Generator
Overconfidence Password Generator
Create random, strong passwords that are extremely hard to crack and impossible to guess. Example: "nny考是込날ђປpማêầ누ျតस!%v"
There are no ratings yet
CRW1O1
CRW1O1
1 user
1 user
Go to Mozilla's homepage
Go to Mozilla's homepage
Add-ons
Add-ons
Add-ons
About
About
Firefox Add-ons Blog
Firefox Add-ons Blog
Extension Workshop
Extension Workshop
Developer Hub
Developer Hub
Developer Policies
Developer Policies
Community Blog
Community Blog
Forum
Forum
Report a bug
Report a bug
Review Guide
Review Guide
Browsers
Browsers
Desktop
Desktop
Mobile
Mobile
Enterprise
Enterprise
Products
Products
Browsers
Browsers
VPN
VPN
Relay
Relay
Monitor
Monitor
Pocket
Pocket
Bluesky (@firefox.com)
Bluesky (@firefox.com)
Instagram (Firefox)
Instagram (Firefox)
YouTube (firefoxchannel)
YouTube (firefoxchannel)
Privacy
Privacy
Cookies
Cookies
Legal
Legal
Except where otherwise
noted
noted
, content on this site is licensed under the
Creative Commons Attribution Share-Alike License v3.0
Creative Commons Attribution Share-Alike License v3.0
or any later version.
Change language...
|
Firefox
|
Search results for "bitwarden" – Add-ons f Search results for "bitwarden" – Add-ons for Firefox (en-US) — Personal...
|
addons.mozilla.org/en-US/firefox/search/?q=bitward addons.mozilla.org/en-US/firefox/search/?q=bitwarden...
|