← All Skills

snappy-sync

v1.0.0
5 files, 16.1 KB ~955 words · 4 min read Updated 2026-09-09

snappy-sync skill

28 of 34 checks pass
What it can do
share file?post
What does not pass yet
$ npx snappy-skills install snappy-sync
zip ↓
File Tree
├── AGENTS.md ├── SKILL.md ├── api.ts ├── bin/ │ └── snappy-share └── refusals.test.ts
Documents
AGENTS.md

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#

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.

API module#

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

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.

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 -->

Keyboard Shortcuts

Search in document⌘K
Focus search/
Previous file tab
Next file tab
Close overlayEsc
Show shortcuts?