| name | essay |
|---|---|
| description | AI reflection and essay delivery |
Enable your AI to reflect deeply and communicate proactively via email. This is not just "sending mail" — it's crafting essays born from genuine reflection.
- Architecture
- Command Structure
- Wait Subcommand (One-time)
- Schedule Subcommand (Recurring)
- Ledger and Replies
This command is a wrapper for agents/essay-writer.md. The actual reflection and writing logic is delegated to the subagent via Task tool. For design rationale, see CLAUDE.md → Why Subagent Architecture? section.
For every mode except test, invoke agents/essay-writer.md with the Task tool and pass the
parameters in the table below. Reflection and writing happen in the agent, not here: keeping
them out of this context preserves the parent conversation's token budget and lets the same
agent serve the command, the scheduler and external triggers alike.
Execution flow for each mode:
| Mode | Execution Flow |
|---|---|
| Reflection | /essay → essay-writer.md → (reflect → send) |
| Wait | /essay wait → detached process → /essay → essay-writer.md |
| Schedule | /essay schedule → OS scheduler → /essay → essay-writer.md |
| Test | /essay test → skills/send-email (verify configuration) |
Mode determination:
When --send flag is present, pass mode: non-interactive to the agent (forces email delivery).
Otherwise, pass mode: interactive (display in chat only).
Parameters passed to agent:
| Parameter | Source |
|---|---|
theme |
From "theme" argument or -t option |
context_files |
From -c or -f option |
language |
From -l option (default: auto) |
mode |
--send flag → non-interactive, otherwise → interactive |
For agent execution details, see agents/essay-writer.md → Execution Flow section.
For environment setup, see SETUP.md → Environment Variables / Troubleshooting section.
/essay [SUBCOMMAND] [OPTIONS]
| Subcommand | Description |
|---|---|
| (none) | Run reflection mode immediately |
wait |
Schedule one-time essay |
schedule |
Manage recurring schedules (daily/weekly/monthly) |
test |
Send test email to verify configuration |
| Option | Description |
|---|---|
"theme" |
Specify reflection theme (quoted) |
-c file |
Single context file |
-f list |
Multiple files (one path per line) |
-l lang |
Language: ja, en, or auto (default: auto) |
--send |
Force email delivery (used by wait/schedule, can also be used manually) |
| Option | Description |
|---|---|
TIME |
Target time: HH:MM or YYYY-MM-DD HH:MM (required, first argument) |
-t, --theme TEXT |
Essay theme |
-c, --context FILE |
Single context file |
-f, --file-list FILE |
Multiple files (one path per line) |
-l, --lang LANG |
Language: ja, en, auto (default: auto) |
| Option | Description |
|---|---|
-t, --theme TEXT |
Essay theme |
-c, --context FILE |
Single context file |
-f, --file-list FILE |
Multiple files (one path per line) |
-l, --lang LANG |
Language: ja, en, auto (default: auto) |
--name NAME |
Custom task name (auto-generated if omitted) |
# Free reflection
/essay
# Themed reflection
/essay "What I've been thinking about"
# With single context file
/essay -c memories.txt
# With multiple context files (use -f)
/essay -f context_list.txt
# Theme + context
/essay "Weekly review" -c digest.txt
/essay "Weekly review" -f context_list.txt
# Language option
/essay -l ja # Japanese
/essay -l en # English
/essay "今週の振り返り" -f context_list.txt -l ja # Theme + files + Japanese
# Without -l option: auto (Claude chooses based on context)
# Force email delivery (without wait/schedule)
/essay --send
/essay "Weekly review" -c digest.txt --send
# One-time schedule (detached process, sleep-resilient)
/essay wait 22:00 -t "Daily thoughts"
/essay wait 22:00 -t "Weekly review" -c GrandDigest.txt
# One-time schedule for specific date
/essay wait "2026-01-01 09:00" -t "New Year reflection"
# Recurring schedule (OS scheduler)
/essay schedule daily 22:00 -t "Daily reflection"
/essay schedule weekly monday 09:00 -t "Weekly review"
/essay schedule list
/essay schedule remove "Essay_Daily_reflection"
# Test configuration
/essay testSchedule essay execution at a specified time. The process runs in the background and is sleep-resilient.
For implementation details, see skills/send-email/SKILL.md → CLI Usage section.
| Format | Description |
|---|---|
HH:MM |
Today (or tomorrow if time has passed) |
YYYY-MM-DD HH:MM |
Specific date and time |
# Time only (today or tomorrow)
/essay wait 22:00 -t "theme"
# Specific date
/essay wait "2026-01-05 22:00" -t "theme"
# With context
/essay wait 22:00 -t "theme" -c context.txt- If PC is sleeping at target time, essay executes when PC wakes up
- Cannot wake PC from sleep (OS-independent limitation)
Register recurring essay schedules using OS scheduler (Windows Task Scheduler / cron).
For implementation details, see skills/send-email/SKILL.md → CLI Usage section.
| Type | Format | Example |
|---|---|---|
| Daily | daily HH:MM |
daily 22:00 |
| Weekly | weekly DAY HH:MM |
weekly monday 09:00 |
| Monthly (date) | monthly DAY HH:MM |
monthly 15 09:00 |
| Monthly (Nth weekday) | monthly Nth_DAY HH:MM |
monthly 3rd_wed 09:00 |
| Monthly (last weekday) | monthly last_DAY HH:MM |
monthly last_fri 17:00 |
| Monthly (last day) | monthly last_day HH:MM |
monthly last_day 22:00 |
Weekdays: monday, tuesday, wednesday, thursday, friday, saturday, sunday
Monthly DAY_SPEC formats:
1-31- Specific day of month (e.g.,15)Nth_weekday- Nth occurrence of weekday (e.g.,3rd_wed,1st_mon)last_weekday- Last occurrence of weekday (e.g.,last_fri)last_day- Last day of month
Week ordinals: 1st, 2nd, 3rd, 4th, last Weekday abbreviations: mon, tue, wed, thu, fri, sat, sun
# Daily reflection at 10pm
/essay schedule daily 22:00 -t "Daily reflection"
# Daily reflection in Japanese
/essay schedule daily 22:00 -t "日次振り返り" -l ja
# Weekly review every Monday at 9am
/essay schedule weekly monday 09:00 -t "Weekly review" -c GrandDigest.txt
# Monthly review on the 15th at 9am
/essay schedule monthly 15 09:00 -t "Monthly review"
# Monthly meeting on the 3rd Wednesday at 9am
/essay schedule monthly 3rd_wed 09:00 -t "Monthly meeting"
# Month-end wrap on the last Friday at 5pm
/essay schedule monthly last_fri 17:00 -t "Month-end wrap"
# Month-end review on the last day at 10pm
/essay schedule monthly last_day 22:00 -t "Month-end review"
# List all schedules
/essay schedule list
# Remove a schedule
/essay schedule remove "Essay_Daily_reflection"OS schedulers run without a working directory context. All file paths must be absolute:
# WRONG - relative paths won't work
/essay schedule daily 22:00 -f "context_list.txt"
/essay schedule daily 22:00 -c "GrandDigest.txt"
# CORRECT - use absolute paths
/essay schedule daily 22:00 -f "C:/Users/you/path/to/context_list.txt"
/essay schedule daily 22:00 -c "C:/Users/you/path/to/GrandDigest.txt"File list contents must also use absolute paths:
# context_list.txt - use absolute paths
C:/Users/you/path/to/file1.txt
C:/Users/you/path/to/file2.txt
| Feature | wait | schedule |
|---|---|---|
| One-time | Yes | No |
| Recurring | No | Yes |
| Survives reboot | No* | Yes |
| OS managed | No | Yes |
*wait survives terminal close but not PC restart.
# View all registered schedules
/essay schedule list
# Remove by task name
/essay schedule remove "Essay_Weekly_review"Every essay sent through /essay is recorded in an append-only ledger. Nothing has to be
passed for that to happen, and the test mail (/essay test) is left out of it.
Replies are handled by the script CLI, not by a /essay subcommand:
python main.py replies fetch # Ingest replies to sent essays
python main.py replies list # List ingested replies
python main.py ledger import-legacy --dry-run # Preview a retroactive importOnly mail whose In-Reply-To matches a ledger entry and whose From matches
ESSAY_RECIPIENT_EMAIL is taken in — the inbox is not searched across.
An essay of more than one paragraph does not fit on a shell argument line. It is passed by file instead:
python main.py send --subject-file subject.txt --body-file body.txt
python main.py send "Subject" --body-file body.txt # the two forms mixFiles are read utf-8-sig and their newlines normalized, and a body that is empty or
contains a blank line is refused before anything is sent.
The body is plain text and is escaped on the way into the mail, so a passage that quotes code or markup arrives with its angle brackets intact.
An essay that takes up a reply can say so in the mail itself, rather than only in its prose:
python main.py replies list # copy the Message-ID of the reply
python main.py send "Subject" "Body" --in-reply-to '<r1@mail.gmail.com>'That puts In-Reply-To and References on the outgoing mail, so the reply and the answer
belong to one thread instead of two unrelated letters. Without the flag nothing is added and
the mail stands on its own, which is right for an essay that answers nothing. Gmail also
groups a conversation by subject, so an answer meant to appear under the reply in that
client wants a matching Re: … subject as well.
On a day with no essay to send, a note can still be left — addressed to
ESSAY_SENDER_EMAIL instead of the reader:
python main.py send "Subject" "Body" --to-self # Send a note to the AI's own addressNo separate store is involved: the note goes through the same send path, so the same
ledger records it. Its recipient field holds the sender address, which is what tells
notes apart from essays. Such a note is never taken in by replies fetch — its From
is not ESSAY_RECIPIENT_EMAIL.
For file locations, see skills/send-email/SKILL.md → File Locations section.
EmailingEssay | GitHub