Agent skill

email-triage

Triage Joel's email inboxes via the joelclaw email CLI. Scan, categorize, archive noise, surface actionable items, and draft replies. Use when: 'check my email', 'scan inbox', 'triage email', 'what needs a reply', 'clean up inbox', 'archive junk', 'email summary', 'anything important in email', or any request involving email inbox review or cleanup.

Stars 51
Forks 3

Install this agent skill to your Project

npx add-skill https://github.com/joelhooks/joelclaw/tree/main/skills/email-triage

SKILL.md

Email Triage

Scan Joel's email inboxes (Front), triage conversations by importance, archive noise, and surface items needing attention. All operations use the joelclaw email CLI.

Canonical Email Interface

  • Front is canonical for all email triage in joelclaw.
  • Never use gog gmail for triage[email protected], VIP threads, and all inboxes are in Front.
  • Use gog for Google Workspace operations (Calendar, Drive, Docs, etc.), not email triage.

Front Search API Reference

The search endpoint is GET /conversations/search/{url_encoded_query}. Results sorted by last activity date (not configurable).

Valid is: statuses

open, archived, assigned, unassigned, snoozed, trashed, unreplied, waiting, resolved

There is NO is:unread. Use is:unreplied for conversations where the last message was inbound.

Status conflicts (cannot combine):

  • archivedopentrashedsnoozed (mutually exclusive)
  • assignedunassigned (mutually exclusive)

Date filters — UNIX TIMESTAMPS ONLY

  • before:<unix_seconds> — messages/comments created before this timestamp
  • after:<unix_seconds> — messages/comments created after this timestamp
  • during:<unix_seconds> — messages/comments on same day as timestamp

Front does NOT accept before:YYYY-MM-DD — always convert to unix seconds. The CLI --before and --after flags accept YYYY-MM-DD and convert automatically.

Recipient filters

  • from:<handle> — sender (email, social handle)
  • to:<handle> — recipient (includes to/cc/bcc)
  • cc:<handle>, bcc:<handle> — specific fields
  • recipient:<handle> — any role (from, to, cc, bcc)
  • Multiple same-type filters use OR logic: from:[email protected] from:[email protected] → either
  • Different filter types use AND logic: from:[email protected] to:[email protected] → both

Entity filters (use IDs, not names)

  • inbox:<inbox_id> — e.g. inbox:inb_41w25
  • tag:<tag_id> — e.g. tag:tag_13o8r1
  • assignee:<teammate_id> — e.g. assignee:tea_hjx3
  • participant:<teammate_id>, author:<teammate_id>, mention:<teammate_id>, commenter:<teammate_id>
  • contact:<contact_id>, link:<link_id>
  • custom_field:"<name>=<value>"

Free text

Bare words search subject + body. Phrases in quotes: "exact phrase".

No negation

Front search has no negation — no -from:, no NOT, no exclusion operators.

Max 15 filters per query.

CLI Commands

Scan inbox

bash
joelclaw email inbox                          # default: is:open, 50 results
joelclaw email inbox -n 100                   # more results
joelclaw email inbox -q "is:open is:unreplied"  # awaiting reply
joelclaw email inbox --from [email protected]  # by sender
joelclaw email inbox --before 2026-02-01      # auto-converts to unix ts
joelclaw email inbox --after 2026-01-15       # auto-converts to unix ts
joelclaw email inbox --page-token "TOKEN"     # pagination (from previous response)

Flags can be combined:

bash
joelclaw email inbox --from [email protected] --after 2026-02-01 -n 20

Archive single

bash
joelclaw email archive --id cnv_xxx

Archive multiple by ID (fast, parallel, batched)

bash
joelclaw email archive-ids --ids cnv_abc,cnv_def,cnv_ghi

Runs 10 concurrent requests. Best for triaging a page of results — grab the IDs of noise and blast them.

Archive bulk by query (dry-run by default)

bash
joelclaw email archive-bulk -q "is:open from:[email protected]"           # dry run — shows count + sample
joelclaw email archive-bulk -q "is:open from:[email protected]" --confirm  # execute
joelclaw email archive-bulk -q "is:open from:[email protected]" --limit 100 --confirm  # batch size

Read a conversation

bash
joelclaw email read --id cnv_xxx
joelclaw email read --id cnv_xxx --refresh   # bypass local cache

joelclaw email read uses a local thread + attachment cache (default TTL: 60 minutes). Cache path: ~/.cache/joelclaw/email/. Use --refresh to bypass cache and force a fresh fetch from Front.

Read output shape + jq patterns

joelclaw email read returns:

text
result.conversation: {id, subject, status, from: {name, email}, date, tags}
result.messages[]: {id, from: {name, email}, date, is_inbound, body_preview (or body), attachments[]}
result.attachment_summary: {total, cached, metadata_only, cache_errors}
result.cache: {hit, source, cache_path, age_seconds, ttl_seconds}

Message content is currently in body_preview, with a migration to body underway. Treat both as valid for backwards compatibility.

Correct extraction pattern (current field):

bash
joelclaw email read --id cnv_xxx 2>&1 | jq '.result.messages[] | {from: .from.email, date: .date, body: .body_preview}'

Backwards/forwards-compatible extraction pattern:

bash
joelclaw email read --id cnv_xxx 2>&1 | jq '.result.messages[] | {from: .from.email, date: .date, body: (.body // .body_preview)}'

List inboxes

bash
joelclaw email inboxes

Triage Workflow

1. Load inbox state

bash
joelclaw email inbox -n 50

Parse the JSON result. Each conversation has: id, subject, from (name + email), date, status, tags.

Useful follow-up queries:

bash
joelclaw email inbox -q "is:open is:unreplied" -n 50   # awaiting reply
joelclaw email inbox --before 2026-01-01 -n 50          # old stuff to clean
joelclaw email inbox --from [email protected]    # CI noise check

2. Categorize using inference

Read each conversation and decide its category based on sender, subject, and context. Do NOT use hardcoded domain lists. Use judgment:

  • Reply needed — Real people expecting a response. Colleagues, collaborators, friends, business contacts with personal messages. Look for reply threads (Re:), questions, invitations to specific meetings, requests.
  • Read later — Interesting content worth saving. Newsletters Joel subscribes to intentionally (The Information, Astral Codex Ten, Lenny's Newsletter), industry news, technical deep-dives.
  • Actionable — Requires action but not a reply. Bills, security alerts, expiring trials, tax documents, delivery updates for real orders, calendar invites needing RSVP.
  • Archive — No value. Marketing spam, promotional offers, cold outreach, duplicate notifications, resolved alerts, automated reports nobody reads, vendor upsells.

3. Present triage summary

Organize findings for Joel. Lead with what matters:

## 🔴 Reply needed (N)
- **Name** — Subject (why it needs a reply)

## ⚡ Actionable (N)
- **Sender** — Subject (what action)

## 📖 Read later (N)
- **Source** — Subject

## 🗑️ Archive candidates (N)
- Count by type (e.g., "14 marketing, 8 CI failures, 5 duplicate notifications")

4. Execute decisions

Fastest path for noise: scan a page, collect noise IDs, use archive-ids:

bash
joelclaw email archive-ids --ids cnv_aaa,cnv_bbb,cnv_ccc,cnv_ddd

For sender-based cleanup: use archive-bulk with from: filter:

bash
joelclaw email archive-bulk -q "is:open from:[email protected]" --limit 100 --confirm

Rate limiting: Front allows ~50 req/s. If archiving large batches (>200), add pauses between batches or expect 429s. The CLI handles batching for archive-ids (10 concurrent), but archive-bulk iterates page-by-page and may hit limits on very large sets.

Read before deciding:

bash
joelclaw email read --id cnv_xxx

Key Context

  • Joel has 8 Front inboxes across [email protected], [email protected], [email protected], [email protected], [email protected], LinkedIn, DMs, and Inngest
  • joelclaw email inboxes lists them all with IDs
  • Joel's teammate ID: tea_hjx3
  • The CLI handles Front API auth automatically via secrets lease front_api_token
  • Draft-then-approve for replies — never send directly
  • Front search results are eventually consistent — recently archived items may still appear in search for a few minutes
  • Pagination: responses include next_page_token when more results exist; pass via --page-token
  • [aih] subject prefix indicates AI Hero project threads via [email protected] Google Group. Key participants: Alex Hillman ([email protected]), Matt Pocock ([email protected]), Amy Hoy ([email protected]). Treat as VIP: always surface, never archive.

Signals for "Reply Needed"

These are heuristics, not rules. Use judgment for each:

  • Re: prefix + real person sender (not a bot/noreply)
  • [aih] prefix — AI Hero collaboration via [email protected] (Alex Hillman, Matt Pocock, Amy Hoy). VIP: always surface, never archive.
  • Direct questions in subject line
  • Meeting invitations from known contacts
  • Threads where Joel was the last sender and someone replied
  • Slack notification summaries (may indicate missed conversations worth checking)

Signals for "Archive"

  • noreply@, no-reply@, notifications@ senders with no actionable content
  • Marketing subject patterns: "LAST chance", "% off", "deal", "unlock", "limited time"
  • Duplicate conversations (same subject from same sender — archive all but most recent)
  • Resolved monitoring alerts (RESOLVED in subject)
  • CI failure notifications older than 24h (stale — either fixed or won't be)
  • Cold outreach from unknown senders with sales language

Common Noise Senders (bulk-archive candidates)

These are historically high-volume, low-signal senders. Use archive-bulk with from: filter:

[email protected]        — CI failures, dependabot, PR notifications
[email protected]   — resolved uptime alerts
[email protected]  — neighborhood spam

Always dry-run first to verify the query matches what you expect.

Expand your agent's capabilities with these related and highly-rated skills.

joelhooks/joelclaw

skill-review

Audit and maintain the joelclaw skill inventory. Use when checking skill health, fixing broken symlinks, finding stale skills, or running the skill garden. Triggers: 'skill audit', 'check skills', 'stale skills', 'skill health', 'skill garden', 'broken skill', 'skill review', 'fix skills', 'garden skills', or any task involving skill inventory maintenance.

51 3
Explore
joelhooks/joelclaw

cli-design

Design and build agent-first CLIs with HATEOAS JSON responses, context-protecting output, and self-documenting command trees. Use when creating new CLI tools, adding commands to existing CLIs (joelclaw, slog), or reviewing CLI design for agent-friendliness. Triggers on 'build a CLI', 'add a command', 'CLI design', 'agent-friendly output', or any task involving command-line tool creation.

51 3
Explore
joelhooks/joelclaw

daily-summary

Generate a daily system activity summary across all joelclaw subsystems. Triggers on 'daily summary', 'what happened today', 'system report', 'today's tally', 'activity summary', 'what did we do', 'daily report'.

51 3
Explore
joelhooks/joelclaw

inngest-durable-functions

Create and configure Inngest durable functions. Covers triggers (events, cron, invoke), step execution and memoization, idempotency, cancellation, error handling, retries, logging, and observability.

51 3
Explore
joelhooks/joelclaw

recall

Fan-out search across all memory sources when context is unclear or vaguely referenced. Triggers on: 'from earlier', 'remember when', 'what we discussed', 'that thing with', 'the conversation about', 'did we ever', 'what happened with', 'you mentioned', 'we talked about', 'earlier today', 'last session', 'the other day', or any vague reference to past context that needs resolution before the agent can act.

51 3
Explore
joelhooks/joelclaw

inngest-local

Set up self-hosted Inngest on macOS as a durable background task manager for AI agents. Interactive Q&A to match intent — from Docker one-liner to full k8s deployment with persistent state. Use when: 'set up inngest', 'background tasks', 'durable workflows', 'self-host inngest', 'event-driven functions', 'cron jobs', or any request for a local workflow engine.

51 3
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results