How the sls command finds the newest screenshot, loads it into Hermes, and gets it analyzed with vision – the current implementation and how to extend it.
1. What It Does
sls (“see latest screenshot”):
- Finds the newest image in
$SCREENSHOTDIR(default~/Pictures/Screenshots; in this workspace it is set to~/av/ast/img/screenshots). - Copies it to a space-free temp path (
/tmp/sls_latest.png) – vision tooling breaks on paths with spaces. - Runs a one-shot Hermes call (
hermes -z) with a prompt instructing the agent to usevision_analyzeon that path. - The
screenshot_toolskill makes the same flow work in-session: when the user typesslsor “see latest screenshot”, the agent finds the latest file, copies it, and callsvision_analyzeon it.
2. Implementation
The command is a small bash script in ~/av/bin/sls (the workspace bin dir is on PATH):
#!/usr/bin/env bash
# sls -- see-latest-screenshot
# Finds the newest screenshot in SCREENSHOTDIR and asks Hermes to analyze it.
#
# Usage:
# sls # describe the latest screenshot
# sls "your question" # ask a specific question about it
SCREENSHOTDIR="${SCREENSHOTDIR:-$HOME/Pictures/Screenshots}"
LATEST=$(find "$SCREENSHOTDIR" -maxdepth 1 \
\( -name "*.png" -o -name "*.jpg" -o -name "*.jpeg" \) \
-print0 2>/dev/null \
| xargs -0 ls -t 2>/dev/null | head -1)
if [[ -z "$LATEST" ]]; then
echo "sls: no screenshots found in $SCREENSHOTDIR" >&2
exit 1
fi
# Copy to a space-free tmp path -- vision_analyze breaks on paths with spaces
TMPFILE="/tmp/sls_latest.png"
cp "$LATEST" "$TMPFILE"
QUESTION="${1:-Describe everything you see in this screenshot in detail.}"
echo "sls: loading $LATEST" >&2
PROMPT="Use vision_analyze to look at the image at this path: ${TMPFILE}
Question: ${QUESTION}"
exec hermes -z "$PROMPT"2.2 The Hermes skill
The screenshot_tool skill (at ~/.hermes/skills/screenshot_tool/SKILL.md) handles the in-session flow:
- Triggers: user says
sls, “see latest screenshot”, “show latest screenshot”, “look at latest screenshot”, or “what’s on my screen”. - Steps: find the most recent file in
$SCREENSHOTDIR(same find pipeline as the script), then callvision_analyzewith the path exactly as given – no URL-encoding.
2.3 Registration
- The script is executable in
~/av/bin/(the workspace PATH convention). - The skill lives at
~/.hermes/skills/screenshot_tool/and is picked up when Hermes loads its skills. SCREENSHOTDIRis exported in the shell environment.
2.4 Restart / reload
- PATH changes need a new shell.
- Skill changes need a Hermes session restart.
3. How It Works Internally
- File discovery:
findlists.png/.jpg/.jpegfiles one level deep;xargs -0 ls -t | head -1picks the newest by mtime (space-safe via null separators). - Normalization: the file is copied to
/tmp/sls_latest.pngso the path handed to the vision tool has no spaces. - Invocation:
hermes -zruns a one-shot agent call with a prompt containing the path and the question. - Vision tool auto-trigger: the prompt tells the agent to use
vision_analyze(image_url=/tmp/sls_latest.png); the skill triggers the same call when the user typesslsin-session.
Why find + xargs -0 instead of a plain glob? - Handles filenames with spaces safely (-print0 / -0). - Faster than a Python glob for directories with thousands of screenshots. - ls -t gives the newest by modification time without per-file stat calls in the shell.
4. Testing the Command
Manual test:
- Ensure you have screenshots in
$SCREENSHOTDIR(or the default~/Pictures/Screenshots). - Run
sls– expect “sls: loading” then a vision analysis of the newest image. - Run
sls "what browser tabs are open?"– expect an answer specific to the image. - In-session, type
sls– expect the same analysis without leaving the session.
Debugging:
If the command fails silently: - Check the script’s stderr: run sls directly and read the error. - Verify SCREENSHOTDIR is set correctly for a custom location. - Test the find pipeline manually:
find "${SCREENSHOTDIR:-$HOME/Pictures/Screenshots}" -maxdepth 1 \
\( -name "*.png" -o -name "*.jpg" -o -name "*.jpeg" \) \
-print0 | xargs -0 ls -t | head -1- Check
/tmp/sls_latest.pngexists after a run.
5. Design Considerations
5.1 Error Handling
- Missing/empty
SCREENSHOTDIRor no matching images: prints a message to stderr and exits 1 – never crashes the shell. - The copy to tmp preserves the original; the tmp file is simply overwritten on each run.
5.2 Performance
Finding the newest file in a directory of 10,000+ screenshots: - find + xargs -0 ls -t | head -1: ~100ms - naive shell glob + stat loop: slower and space-fragile
5.3 Security
- No arbitrary command injection: file paths come from
find/ls, not user input; the question argument is passed inside the prompt string, not executed. - The tmp copy avoids path-quoting issues with unusual filenames.
5.4 Extensibility
Future improvements could include: - sls 5 – show the 5 latest screenshots - sls --today – filter by date - sls --dir=/custom/path – override SCREENSHOTDIR - sls --no-vision – just print the path, don’t analyze
6. Best Practices for CLI-Plus-Skill Commands
- Keep the script small – do work in helpers if logic grows.
- Use
findwith-print0/xargs -0– space-safe for real-world filenames. - Normalize to a space-free path before handing to tooling.
- Respect env conventions –
SCREENSHOTDIRwith a sane default. - Make the skill match the script – same discovery logic, same trigger vocabulary, so both entry points behave identically.
- Test on a fresh session – PATH/skill changes take effect on restart.
7. Reverting Changes
Revert via git:
cd ~/av
git checkout -- bin/slsManual revert: - Remove ~/av/bin/sls. - Remove ~/.hermes/skills/screenshot_tool/.
Restart Hermes after any change.
8. Alternative Approaches
Without a script: - In-session, the agent can do it directly: find the latest file in SCREENSHOTDIR, copy to /tmp/sls_latest.png, call vision_analyze. - A shell alias that expands to the same one-shot:
alias sls='hermes -z "Use vision_analyze on /tmp/sls_latest.png"'Want to stay in touch?
- Signal (announcements): https://signal.group/#CjQKIGLn7xDB0uOXMMlbKlsKEG0CmkmL9gk3U0SeIX0KlKRZEhDoqIluCXo84TrBz-2tMJD7
- Signal (discussion): https://signal.group/#CjQKIDA0v6tUciWe-3jRArkbYttju8xfuoczTOfMrGuvhmEZEhCrOnPk-IWFmFmipdI1EHxv
- Signal: archerships.43 (https://signal.me/#eu/9JUc8x9c-QA0_-QR9qQd0HUmjsnAG1BeOJM2nDo5DopjIPq5bThAJYr99lsh0cPP)
- Mailing list: https://archerships.substack.com/subscribe
- Email: [email protected]
- Website: https://archerships.com
- Substack: https://substack.com/@archerships
- Twitter: https://x.com/archerships
- Facebook: https://www.facebook.com/archerships
- Yahihonne: https://yakihonne.com/profile/nprofile1qqsgr0xn6vvr8su9ptzj4n50j8vzmczzayed0wcl5rdnvh0tc6xhqncy6jrjw
- Nostr-npub:
npub1sx7d85ccx0pc2zk99t8glywc9hsy96fj67a3lgxmxew7h35dwp8shak49e - Odysee: https://odysee.com/@archerships:6
- TikTok: https://www.tiktok.com/@archertships
Support my work
- Donations (crypto): https://trocador.app/anonpay/?ticker_to=xmr&network_to=Mainnet&address=85e4n5bgLTWiAWZbkjbbF5MLrwyiU8kjxHWHL9t6vDE5MyNUCPzBuZUNDcvbCisC5iW5PPBP9ETRQUWQQjMuvAhHRFaYCeM&donation=True&simple_mode=True&name=Archerships&[email protected]&ticker_from=xmr&network_from=Mainnet&bgcolor=000000ff
- Donations (fiat): https://ko-fi.com/archerships
- Consulting: privacy / crypto / censorship consulting – email or Signal