Chris Parsons/dreamv1.0.13

dream

Weekly review of all thoughts captured in the past week. Reads new concept notes, saved articles, and daily-note Wiki Ingest sections; identifies patterns across multiple notes and surfaces tensions and open questions. Delivers as an interactive HTML file attached to Telegram — does NOT save a vault note (the user doesn't read them). Triggers on /dream, 'weekly dream', 'what did I think about this week', 'patterns from this week'.

by @chrismdp

What is airskills?

airskills is one home for your SKILL.md files. Standard format, no lock-in — back them up, publish them, and sync across your whole team in one command. Works with Claude Code, Cursor, Copilot, ChatGPT, and more.

Learn more about airskills →

Install this skill

Pick your agent. Free, no account needed for public skills.

One-liner with npx — installs to every detected agent on your machine (~/.claude/skills/,~/.cursor/skills/, and more).

$ npx airskills add chrismdp/dream

Or install the Go CLI once: curl -fsSL https://airskills.ai/install.sh | bash

---
name: dream
description: "Weekly review of all thoughts captured in the past week. Reads new concept notes, saved articles, and daily-note Wiki Ingest sections; identifies patterns across multiple notes and surfaces tensions and open questions. Delivers as an interactive HTML file attached to Telegram — does NOT save a vault note (the user doesn't read them). Triggers on /dream, 'weekly dream', 'what did I think about this week', 'patterns from this week'."
argument-hint: "[--days N]"
allowed-tools: Read, Edit, Write, Glob, Grep, Skill, Bash(date *), Bash(~/.claude/skills/dream/scripts/collect.sh *), Bash(~/.claude/skills/dream/scripts/log-send.sh *), Bash(~/.claude/skills/dream/scripts/recent-dreams.sh *), Bash(~/.claude/skills/dream/scripts/pick-lens.sh *), Bash(~/.claude/skills/telegram/scripts/send-document.sh *), Bash(rg *), Bash(cat *), Bash(wc *), Bash(ls *), Bash(mkdir *)
---

Dream

A weekly pattern-noticing pass over the thoughts the user captured this week. The point is resurfacing what the user themselves wrote — not generating new analysis. If the user reads the dream digest and learns something they hadn't already filed themselves, the dream failed (it should be pulling threads out of the wiki, not inventing them).

Why this exists

The user captures dozens of atomic concept notes a week via /capture, /process-link, /process-transcript, /process-sessions. The vault accumulates value, but they rarely have time to re-read it. The dream is the reading-shaped output of a week's thinking — a top-10 of the user's own material, with the patterns the wiki itself is suggesting.

When this skill runs

  • Richard-owned cron (primary): nightly at 21:00 BST (20:00 UTC) via ~/vault/agents/richard/reflexes/dream.sh. Richard owns the reading-shaped synthesis and routes concrete follow-up threads to other agents when needed.
  • Interactive: the user invokes /dream directly with optional --days N to override the window.

Process

1. Roll tonight's lens — do this first

The lens picker rolls one of 10 angles (random recent note / older surprise / mission audit / counter-current / lateral word / 1-day window / 30-day window / forgotten thread / one person / sit-with-tension). The lens is the angle of attack for tonight's dream — it forces variation across nightly runs.

LENS_LABEL=$(~/.claude/skills/dream/scripts/pick-lens.sh --label)
LENS_PROMPT=$(~/.claude/skills/dream/scripts/pick-lens.sh)
echo "Lens: $LENS_LABEL"
echo "$LENS_PROMPT"

Some lenses override the input window (window:3days, window:90days) — adjust the --days flag to collect.sh accordingly. Default window is 30 days (the past month of thoughts) — a month gives a wide enough random-pool for the lens to sample from so each night feels different.

2. Read what was already sent recently — avoid repeating

~/.claude/skills/dream/scripts/recent-dreams.sh 5

This prints the last 5 nights of Telegram messages. Read them. The whole point of the lens roll is so each night feels different — but the harder discipline is not re-surfacing threads the user has just read. If a tension was named last night, don't lead with it tonight; pick something else from this week's material, or sit with the lens.

3. Gather the month's material

~/.claude/skills/dream/scripts/collect.sh --days 30 > /tmp/dream-input.md
wc -l /tmp/dream-input.md

(If the lens overrode the window — window:3days or window:90days — use that value instead of 30.)

The collector produces a single markdown blob with:

  • New atomic concept notes (vault root *.md created in window)
  • New entries in links/reference/ (saved articles, transcripts, PDFs)
  • "### Wiki Ingest" sections from each daily note in the window
  • Active projects (status: doing or todo)

If --days N was passed to /dream, pass it through to collect.sh.

4. Read the input through tonight's lens

Read /tmp/dream-input.md end to end, but with tonight's lens as the active filter. The lens overrides "find the dominant pattern" — if tonight's lens is forgotten-thread, the dream is about a forgotten thread, even if the dominant pattern is something else.

The input is the past 30 days — much wider than a weekly pool, deliberately, so each night's random sample can land on a genuinely different corner of recent thinking. Bias away from "the loudest material from the past week" and towards the corner the lens picked, even if it's quieter.

General skim for:

  • Recurring entities — names, companies, concepts that appear across multiple notes
  • Counter-current ideas — notes that contradict or extend other notes
  • Strategic flags — anything that touches the user's mission, active client work, or open commercial commitments
  • Threads NOT in the recent-dreams log — bias hard towards material the past 5 nights haven't named

5. Run vault searches to find depth (only if the lens needs them)

For the threads you're considering surfacing, run targeted ripgrep searches with several distinctive phrases:

rg -i "<theme>|<specific phrase>|<named person>" ~/vault ~/code/blog/_posts ~/code/blog/pages | head -80

This reveals what the user has already written about the theme over time so the dream can connect old wiki to new notes ("this is the 4th note on X; previous: ..."). Keep it to 1-2 searches for a nightly run; if results are noisy, refine the phrase rather than widening the scan.

6. Compose an interactive HTML dream

Telegram is the only delivery surface, but the content is an HTML file attached to it — not the message body. Do not write a vault note or append to the daily note. The user does not read dream notes — the file either lands in Telegram and gets opened, or it doesn't land at all. The Telegram caption is just a doorway.

Why HTML, not text. Text dreams stop landing once the format goes stale and the prose blurs together. Interactive HTML — short atoms, visible connections, SVG diagrams, mobile-friendly layouts — keeps the user engaging with their own thinking. The format should vary each night to stay fresh.

Mobile-first, non-negotiable. The user reads the dream on their phone. That means:

  • Single-column at narrow widths; multi-column only on wide.
  • No off-canvas side panels, no click-to-fetch-detail patterns — those fail on touch.
  • No external assets (no CDN fonts, no remote SVG, no analytics). Self-contained file, opens with no network.
  • Text scales sensibly; tap targets ≥ 40px.
  • <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"> always.

No JavaScript — interactivity must be pure HTML/CSS. Telegram's in-app browser sandboxes/strips inline onclick and <script>, so any JS-driven tap-to-reveal silently does nothing — the cards look tappable but don't open. This has shipped broken (2026-05-26: question-cards used onclick="this.classList.toggle('open')", nothing expanded). Build every expand/collapse with native <details><summary>…</summary>…</details> (style the marker via summary::-webkit-details-marker{display:none} and a [open] selector for the +/− glyph). Carousels: scroll-snap-type. Scroll-to: plain #anchor links. If you cannot build the interaction without JS, make it static instead — never ship a control that needs JS to function.

No dead links. Don't emit <a href="#"> or <a> pointing at vault note titles — the reader is on a phone with no vault access, so they go nowhere and read as broken. Reference concept notes as plain emphasised text (<em>), not anchors. Only use real, tappable https:// URLs as links.

Content shape (still):

  • Tonight's lens stated up top, one line, italic.
  • 2–4 threads. Lens drives which threads.
  • Each thread ends with a question, not a decision. The dream surfaces unresolved threads — let the reader resolve them.
  • Connections, not categories. Name the people, conversations, dates, projects. Cross-thread bridges shown visually, not buried in prose.
  • Almost no body prose. Long paragraphs of inline citations die on mobile. Decompose each thread into 4–6 short attributed atoms (one sentence each, with attribution) and let the layout do the connecting work.

Format rotation — pick a DIFFERENT one each night. This is the format equivalent of the lens roll. Check recent-dreams.sh 5 and explicitly pick a format that hasn't been used recently. The format axis is independent of the lens axis. Menu (extend it):

Format Best for Sketch
Constellation + carousels 2–4 threads with explicit bridges SVG of nodes + bridges at top, horizontal swipeable strips of attributed atoms below
Timeline window:7days / window:30days / window:90days — date-anchored thinking Horizontal time axis with thought-dots; clicking a dot reveals the atom
Quote wall one-person lens or a single dominant voice Big quote cards as heroes, with attribution and a small "where this connects" footer
Sankey-style flow Many sources feeding into fewer themes feeding into one or two questions SVG flows source → theme → question; widths proportional to weight
Tarot spread sit-with-tension lens — 3 cards laid down 3 large flip cards (past / present / question), each face-up with one image and one sentence
2D matrix Tension between two axes (e.g. internal/external × commercial/mission) Cells contain atoms; empty cells are the actual interesting question
Force-graph forgotten-thread lens — show how the thread connects Static SVG of nodes + edges, no JS physics; tappable nodes that scroll to atoms
Map / spatial Cross-client patterns Geographic-style layout, clients as places, threads as roads between them
One big diagram + annotations A single concept with multiple facets Hero SVG centre, marginalia atoms pointing in
Question-first mission-audit lens — the question is the lead 3 big questions as cards; tap reveals the evidence atoms behind it

SVG diagrams — make concepts visual. Use SVG aggressively. Inline it (no external files). Patterns that work:

  • Node-and-edge constellations — small filled circles for threads, dashed lines for bridges, labels on the lines, all in one <svg viewBox>. Keep the viewBox aspect ratio modest (e.g. 600×160) so it stays legible on mobile.
  • Spectrums and gradients — a horizontal axis with thought-dots placed along it (e.g. "fully automated ↔ fully human")
  • Concentric shells — surface/middle/deep layers showing what's visible vs hidden (great for the visibility-crisis theme)
  • Sankey-lite — <path> curves between source and destination columns
  • Spot-illustrations — a single small SVG inside a card to make a concept land (a broken ladder for the apprenticeship-rung idea, a magnifying glass with a hole for visibility, etc.). They don't have to be pretty — they have to point.

Inline SVG with viewBox + preserveAspectRatio="xMidYMid meet" scales correctly on phones without extra CSS. Use CSS variables for colour so the diagram inherits the page palette.

Visual language guidelines:

  • Dark background by default (most users read at night). One --bg, one --ink, 2–4 accent colours mapped to threads.
  • A monospace face for metadata (lens, dates, tags); a system sans for everything else. Don't load fonts — use -apple-system / system stack.
  • Generous whitespace. Atom cards 14–22px padding minimum.
  • Each thread gets ONE colour and that colour is consistent everywhere it appears (heading, pager dot, question border, SVG node).
  • Use scroll-snap-type: x mandatory for horizontal carousels — native, no JS, perfect on mobile touch.
  • Tap target minimum 40×40px.

Length target: 8–25 KB file size. Big enough for SVG + interactivity; small enough that it loads instantly in Telegram's in-app browser.

Output paths:

  • /tmp/dream-YYYY-MM-DD.html — the file you send
  • /tmp/dream-YYYY-MM-DD.summary.txt — a short plain-text recap (thread titles, key entities, the 3 questions, the format used). This is what recent-dreams.sh will show future runs. Keep it under 600 chars. Do not dump the HTML into the log — it bloats the history and makes future format rotation blind.

7. Send as Telegram document + log

Delivery is via the /telegram skill's send-document.sh wrapper — see ~/.claude/skills/telegram/SKILL.md for the full Telegram integration including caption escaping rules and document-attachment behaviour on mobile vs desktop clients.

DATE=$(date +%Y-%m-%d)
HTML=/tmp/dream-$DATE.html
SUMMARY=/tmp/dream-$DATE.summary.txt
FORMAT="constellation+carousels"   # whatever was actually picked

# Compose a brief caption — this is the doorway, not the dream itself.
# Telegram's Markdown parse mode (not MarkdownV2): bold is *single asterisks*, NOT **double**.
# Avoid `_underscores_` and `[brackets]` in the caption — both break the parser.
CAPTION=$(cat <<CAP
🌙 *Dream — $DATE · $LENS_LABEL*

<one-line tease of the threads — e.g. "A reviewer paradox · B HTML deliverable · C visibility crisis">

<one-line on the format — e.g. "swipe each strip; constellation up top shows where threads touch">
CAP
)

# Richard owns Dream, so the document goes out through his bot whether this is
# his nightly reflex or a manual /dream run. Agents send as themselves; there is
# no default bot.
~/.claude/skills/telegram/scripts/send-document.sh "$HTML" --bot-var RICHARD_BOT_TOKEN --caption "$CAPTION"

# Log with the summary (NOT the HTML body)
~/.claude/skills/dream/scripts/log-send.sh "$LENS_LABEL" "$HTML" --format "$FORMAT" --summary "$SUMMARY"

The log-send.sh step is mandatory. Without it, format rotation breaks for the next night. Pass --format so future runs can read what's already been used and pick something different.

Quality bar

  • Connections, not summaries. "Three notes mentioned distributed systems" is bookkeeping. "These three notes are circling the same insight: external validation converts Byzantine failures into crash failures — this is the theoretical core the user keeps approaching from different angles" is dream output.
  • The user's voice, their own thinking. The dream surfaces what the user has already written — it doesn't invent new framings the user didn't put in their notes. If a pattern requires inventing a frame the user never used, demote it.
  • Specific over general. Naming the actual conversation, date, project, or person beats abstractions like "various conversations this week."
  • Mission filter. Weight threads that touch the user's stated mission or guiding theme above generic interesting-but-orphan ideas.
  • Don't pad. If only two real tensions surfaced this week, send two. The dream is not a quota.

Failure modes to reject

  • Restating concept-note bodies (the dream is a connector, not a summary)
  • Inventing patterns from a single note
  • Adding analysis the user didn't write themselves (the dream surfaces the user's thinking, not the agent's)
  • Writing a punch list of actions ("audit proposals, productise X, write blog Y") — action lists were explicitly rejected during development. Surface the questions; let the reader decide.
  • Saving a vault note. The vault note doesn't get read; the file attached to Telegram does.
  • Falling back to a plain Telegram text message. Dream is HTML attached to Telegram. The caption is just the doorway.
  • Re-using the same HTML format two nights running. The format axis is the second variation mechanism (alongside the lens roll). Check recent-dreams.sh 5 for the format: line and pick something else.
  • Click-to-fetch-detail, off-canvas drawers, hover-only tooltips — these patterns fail on mobile and have been tried and reverted. Everything visible inline or via native touch gestures (scroll-snap, swipe).
  • External assets — no CDN fonts, no remote images, no analytics. The file must work offline in Telegram's in-app browser.
  • Long paragraphs of inline prose with bracketed citations. Decompose each thread into 4–6 short attributed atoms.
  • Re-running the same patterns from the past 5 nights — the lens roll + recent-dreams check exist to prevent this.
  • Defaulting back to "top 3 patterns of the week" when the lens picked something different. The lens is the angle of attack — honour it.
  • Dumping the raw HTML into dreams.jsonl (this is what log-send.sh --summary fixes). Without a separate --summary text, future runs see a wall of HTML in recent-dreams.sh and the rotation breaks.
  • Skipping the log-send.sh step at the end. Without it, the variation mechanism breaks for the next night.
5.4 KB
1.9 KB
6.8 KB
1.2 KB
1.7 KB