Skip to content

Repository files navigation

                _       _     _   _     _
 __      ____ _| |_ ___| |__ | |_| |__ (_)___
 \ \ /\ / / _` | __/ __| '_ \| __| '_ \| / __|
  \ V  V / (_| | || (__| | | | |_| | | | \__ \
   \_/\_/ \__,_|\__\___|_| |_|\__|_| |_|_|___/

Drop a file in a folder. An agent wakes up, processes it, and hands off the result.

version license platform part of


watchthis is a launchd-watched folder pipeline. You drop a file into a watched folder; a background agent wakes on its own, runs your handler over the file, and notifies you. It is a scaffold, not a turnkey app: the harness handles all the fiddly launchd plumbing, and you write one handler that does the actual work.

The shipped example transcribes a screen recording (whisper), samples frames (ffmpeg), and writes a plain-language summary (claude -p). Swap the handler and it becomes whatever you want: a build trigger, an image resizer, a CSV importer, an "email me when a render lands" watcher.

Why this exists

launchd watched folders are genuinely useful and genuinely annoying to get right. watchthis packages the parts that took real trial and error:

  • TCC: the watched folder must live outside ~/Documents, ~/Desktop, and ~/Downloads. launchd agents cannot enumerate a watched folder under those, so the inbox lives at home-root (~/<name>/inbox) with a Desktop symlink for dropping.
  • Bare environment: launchd gives you no $HOME and no $PATH. The harness pins both.
  • Settle-wait: a freshly dropped file is still being written. The harness waits for its size to stop changing before touching it.
  • Single-instance lock: WatchPaths can fire several times during one copy. An atomic lock keeps runs from overlapping.
  • Finalize before handoff: the run is moved to its final done/ location before your handler hands off any path. Move it after and the handoff points at an already-empty directory (a bug that is easy to ship and hard to spot).
  • Notifications that actually fire: macOS gates banner notifications unpredictably under launchd, so the high-signal start/done events are spoken aloud, synchronously, so they finish before the job exits.

Quickstart

git clone https://github.com/nigelglenday/watchthis.git ~/watchthis-src
cd ~/watchthis-src

# 1. Edit watchthis.conf (name, file types, notify phrases, handler path)
$EDITOR watchthis.conf

# 2. Write your handler, or use a shipped example
cp examples/transcribe-summarize-handler.sh ~/watchthis/handler.sh

# 3. Install (generates the LaunchAgent, creates the inbox + Desktop drop)
./install.sh

Then drop a file on the watchthis inbox shortcut on your Desktop. Check progress with watchthis status, follow live with watchthis logs.

Writing a handler

A handler is any executable. The harness calls it with two arguments:

#!/bin/bash
SRC="$1"    # the claimed file, e.g. ~/watchthis/done/<run>/source.mp4
WORK="$2"   # the run directory (already finalized under done/)

# ...do your thing, write outputs into $WORK...

Anything you write into $WORK is kept. The harness handles the lifecycle and notifications. What to do with the output (write a file, post somewhere, hand off to another tool) is entirely up to the handler.

Keep your LLM prompt in its own file, not inline in the handler. Prompts are the highest-churn part of the pipeline, and a file is versioned, diffable, and free of shell-escaping. The default handler reads summary.md from next to itself; do the same with your own prompts.

See examples/ for ready-made handlers:

  • transcribe-summarize-handler.sh: the default. Transcript + frames + summary to findings.md.
  • eagent-escalation-handler.sh: hands the result off to a Claude Code session via an eagent inbox.
  • process-capture-handler.sh: turns a narrated workflow walkthrough into a build-ready process spec (steps, systems, pain points, automation opportunities) and routes it to the agent that will build that workflow. The raw transcript is appended to every summary so the receiving agent can verify against exact wording.

The CLI

watchthis status        # is a run active? which file, what stage, how long
watchthis logs          # live tail of the process log
watchthis prune [days]  # strip source media + frames from runs older than N (default 7), keep outputs

Pair prune with a nightly LaunchAgent if your inputs are large (a sample plist is easy to add; see the docs).

Requirements

  • macOS (launchd, osascript, say)
  • bash + coreutils (preinstalled)
  • The default example handler additionally wants whisper, ffmpeg, and the claude CLI. Each step degrades gracefully if a tool is missing.

Layout

watchthis.sh      the harness (you don't edit this)
watchthis.conf    your config: name, file globs, notify phrases, handler path
watchthis         the status / logs / prune CLI
install.sh        generates the LaunchAgent and wires everything
uninstall.sh      unloads + removes it (keeps your runs)
examples/         ready-made handlers
~/<name>/         created on install: inbox/ processing/ done/ logs/

Part of termpaper.dev

A set of terminal tools for managing Claude Code state.

  • a-team: parallel Claude Code session manager
  • skillbox: inventory and manage skills, commands, subagents
  • eagent: multi-session assistant pattern with file-based inboxes
  • crmmy: file-based CRM your agent maintains
  • whispertty: record audio, transcribe, label speakers
  • watchthis: drop a file, an agent processes it and hands off

License

MIT

About

Drop a file in a folder; a launchd agent processes it and hands off the result. A macOS scaffold, part of termpaper.dev.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages