snappy-sync skill
share file?post$ npx snappy-skills install snappy-sync
Robert works on a MacBook Pro. Agents often run via SSH into the Mac Mini. Screenshots and local files on the MBP are invisible to agents on the Mini. This skill solves that: upload → CDN → clipboard URL → paste into chat.
bashsnappy-share # uploads latest ~/Desktop screenshot
snappy-share --region # crosshair capture (like ⌘⇧4) then upload
snappy-share /path/to/file.png # uploads a specific file
Output: the public URL is echoed to stdout, copied to the macOS clipboard via pbcopy, and shown in a display notification. Paste the URL into Claude chat and the agent can curl / read it exactly like any other image.
typescriptimport { share } from "../snappy-sync/api.ts";
const { url } = share("/path/to/file.png");
| Function | Purpose |
|---|---|
share(filePath, context?) |
Upload file via snappy-image/scripts/cdn-upload.sh, return {url, file, bytes}, copy URL to clipboard, fire macOS notification. Default context is shared/ on the robert-storage bucket. |
CLI:
bashnpx tsx ~/.claude/skills/snappy-sync/api.ts share --latest-screenshot
npx tsx ~/.claude/skills/snappy-sync/api.ts share /path/to/file
~/.claude/skills/ is present on the machine. It's synced via the dotfiles repo.~/.claude/skills/snappy-settings/.env.cache is present with DO_SPACES_KEY and DO_SPACES_SECRET. Without this, the upload fails. Copy .env.cache from the Mac Mini once: scp robertboulos@roberts-mac-mini.local:~/.claude/skills/snappy-settings/.env.cache ~/.claude/skills/snappy-settings/.env.cacheln -s ~/.claude/skills/snappy-sync/bin/snappy-share ~/.local/bin/snappy-share (or symlink into any dir on $PATH).snappy-share --help or take a screenshot and run snappy-share. Check the clipboard.Config: ~/.hammerspoon/init.lua
| Hotkey | Action |
|---|---|
⌘⇧U |
Upload latest ~/Desktop screenshot |
⌘⇧I |
Region capture (crosshair like ⌘⇧4) then upload |
⌘⇧Y |
Upload the file currently selected in Finder |
All three copy the CDN URL to clipboard and show a Hammerspoon alert on completion.
snappy-share from the Mac Mini makes no sense — Robert can't see the notification, and the screenshot dir is different.snappy-share anything sensitive (secrets, private docs). For those use scp..env.cache is a secret file. Never snappy-share it.{ms-timestamp}-{slug} key. URLs don't collide and won't be overwritten by subsequent shares.| Skill | Why |
|---|---|
snappy-image |
Owns cdn-upload.sh, the upload primitive this skill wraps |
snappy-settings |
Provides DO_SPACES_KEY / DO_SPACES_SECRET via .env.cache |
dev-terminal |
Home for terminal-side shortcuts and aliases |
Nothing in the collection names this skill.
<!-- SNAPPY-CONTRACT-VERBS-START -->
Generated from api.ts HAND_CONTRACT. Do not hand-edit this block.
| Verb | Contract arguments | Effect | First call |
|---|---|---|---|
share |
file? |
post |
npx tsx ~/.claude/skills/snappy-sync/api.ts share |
When an answer carries face_hint, show it with one snappy_present(<answer>) call.
See /snappy-faces for face selection. Human-facing images must crop to the
element, render at 2x on Retina, and fill the destination channel instead of
placing a small card in a full-page screenshot.
<!-- SNAPPY-CONTRACT-VERBS-END -->
The system spec lives at ~/.claude/skills/snappy-settings/skill-spec.md.
1. Fix gaps (P — proportional). If this AGENTS.md didn't cover your case, edit it inline (1-5 lines). The goal: the next agent doesn't leave the loader.
2. Validate structure.
api.ts exists with typed exports, CLI modeapi.ts calls the cdn-upload.sh directly (no proxy)AGENTS.md has API module section with import + function table + CLI3. Log always.
bashecho "[$(date -u +%FT%TZ)] snappy-sync: <what was missing or fixed> [FIXED|LOGGED]" >> ~/.claude/logs/agents-md-feedback.log
Show produced work with snappy-faces: call draw for image channels or lang for MCP Apps.
<!-- SKILL-INDEX-START -->
[snappy-sync Index]|root: ~/.claude/skills/snappy-sync|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md}
<!-- SKILL-INDEX-END -->
---
name: snappy-sync
role: Cross-machine file sharing between MacBook Pro and Mac Mini. Upload a local file to CDN, copy the public URL to clipboard, so the user can paste it into chat and the agent can read it.
loaded-by: PreToolUse hook (auto-injected when "snappy-sync" is mentioned)
---
# snappy-sync -- Agent Loader
Robert works on a MacBook Pro. Agents often run via SSH into the Mac Mini. Screenshots and local files on the MBP are invisible to agents on the Mini. This skill solves that: upload → CDN → clipboard URL → paste into chat.
## The one move
```bash
snappy-share # uploads latest ~/Desktop screenshot
snappy-share --region # crosshair capture (like ⌘⇧4) then upload
snappy-share /path/to/file.png # uploads a specific file
```
Output: the public URL is echoed to stdout, copied to the macOS clipboard via `pbcopy`, and shown in a `display notification`. Paste the URL into Claude chat and the agent can `curl` / read it exactly like any other image.
## API module
```typescript
import { share } from "../snappy-sync/api.ts";
const { url } = share("/path/to/file.png");
```
| Function | Purpose |
|---|---|
| `share(filePath, context?)` | Upload file via `snappy-image/scripts/cdn-upload.sh`, return `{url, file, bytes}`, copy URL to clipboard, fire macOS notification. Default context is `shared/` on the `robert-storage` bucket. |
CLI:
```bash
npx tsx ~/.claude/skills/snappy-sync/api.ts share --latest-screenshot
npx tsx ~/.claude/skills/snappy-sync/api.ts share /path/to/file
```
## Install on a fresh machine (MBP setup)
1. Ensure `~/.claude/skills/` is present on the machine. It's synced via the dotfiles repo.
2. Ensure `~/.claude/skills/snappy-settings/.env.cache` is present with `DO_SPACES_KEY` and `DO_SPACES_SECRET`. Without this, the upload fails. Copy `.env.cache` from the Mac Mini once: `scp robertboulos@roberts-mac-mini.local:~/.claude/skills/snappy-settings/.env.cache ~/.claude/skills/snappy-settings/.env.cache`
3. Add the wrapper to PATH: `ln -s ~/.claude/skills/snappy-sync/bin/snappy-share ~/.local/bin/snappy-share` (or symlink into any dir on `$PATH`).
4. Verify: `snappy-share --help` or take a screenshot and run `snappy-share`. Check the clipboard.
## Hotkeys (Hammerspoon — active on MBP)
Config: `~/.hammerspoon/init.lua`
| Hotkey | Action |
|---|---|
| `⌘⇧U` | Upload latest `~/Desktop` screenshot |
| `⌘⇧I` | Region capture (crosshair like `⌘⇧4`) then upload |
| `⌘⇧Y` | Upload the file currently selected in Finder |
All three copy the CDN URL to clipboard and show a Hammerspoon alert on completion.
## Rules
1. **MBP-side only for the hotkey.** Running `snappy-share` from the Mac Mini makes no sense — Robert can't see the notification, and the screenshot dir is different.
2. **The URL is public.** DO Spaces is a public CDN. Don't `snappy-share` anything sensitive (secrets, private docs). For those use scp.
3. **The filename becomes part of the URL.** Strip any sensitive details from the filename before sharing.
4. **`.env.cache` is a secret file.** Never `snappy-share` it.
5. **Uploads are immutable.** Each call gets a unique `{ms-timestamp}-{slug}` key. URLs don't collide and won't be overwritten by subsequent shares.
## Uses
| Skill | Why |
|---|---|
| `snappy-image` | Owns `cdn-upload.sh`, the upload primitive this skill wraps |
| `snappy-settings` | Provides `DO_SPACES_KEY` / `DO_SPACES_SECRET` via `.env.cache` |
| `dev-terminal` | Home for terminal-side shortcuts and aliases |
## Used by
Nothing in the collection names this skill.
<!-- SNAPPY-CONTRACT-VERBS-START -->
## Contract verbs
Generated from `api.ts` `HAND_CONTRACT`. Do not hand-edit this block.
| Verb | Contract arguments | Effect | First call |
|---|---|---|---|
| `share` | `file?` | `post` | `npx tsx ~/.claude/skills/snappy-sync/api.ts share` |
## Show the result
When an answer carries `face_hint`, show it with one `snappy_present(<answer>)` call.
See `/snappy-faces` for face selection. Human-facing images must crop to the
element, render at 2x on Retina, and fill the destination channel instead of
placing a small card in a full-page screenshot.
<!-- SNAPPY-CONTRACT-VERBS-END -->
---
## Self-correcting loader (PID feedback)
The system spec lives at `~/.claude/skills/snappy-settings/skill-spec.md`.
**1. Fix gaps (P — proportional).** If this AGENTS.md didn't cover your case, edit it inline (1-5 lines). The goal: the next agent doesn't leave the loader.
**2. Validate structure.**
- `api.ts` exists with typed exports, CLI mode
- `api.ts` calls the `cdn-upload.sh` directly (no proxy)
- `AGENTS.md` has API module section with import + function table + CLI
- No hardcoded tokens
- If any check fails → fix it or log it
**3. Log always.**
```bash
echo "[$(date -u +%FT%TZ)] snappy-sync: <what was missing or fixed> [FIXED|LOGGED]" >> ~/.claude/logs/agents-md-feedback.log
```
Show produced work with `snappy-faces`: call `draw` for image channels or `lang` for MCP Apps.
<!-- SKILL-INDEX-START -->
[snappy-sync Index]|root: ~/.claude/skills/snappy-sync|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md}
<!-- SKILL-INDEX-END -->