Notes
Personal notes. Three types, all stored as individual markdown files with required frontmatter for findability.
Storage
- Root folder:
~/work/notes/ by default. To use a different folder, set the environment variable NOTES_DIR before starting Claude Code, and swap ~/work/notes/ for $NOTES_DIR everywhere in this file.
- Filename:
YYYY-MM-DD_<type>_<topic-slug>.md
- Type is one of:
meeting, idea, fact
- Slug: lowercase, hyphens, no punctuation, max ~50 chars
- Examples:
2026-05-02_meeting_1on1-with-sam.md
2026-05-02_idea_notes-skill-design.md
2026-05-02_fact_supabase-rls-pattern.md
- Frontmatter (required, every note):
---
type: meeting | idea | fact
date: 2026-05-02
title: short human title
tags: [#sam, #acme-corp] # optional, lowercase #word
people: [sam, taylor] # meeting notes only - short names, lowercase
source: email msg:<id> | conversation | link:<url> | null
---
- Body: free-form markdown.
Hard rules
- Always include the full frontmatter block. Missing fields make notes unfindable later.
- Filename strict format.
YYYY-MM-DD_<type>_<topic-slug>.md. No exceptions. Date is today's date from the system context (absolute, never "today" / "Friday").
- Type is one of three.
meeting, idea, fact. If the user is ambiguous, ASK. Don't invent a fourth type.
- Don't auto-tag people. If the user mentions a person without explicitly tagging, ask before adding
#person (same pattern as /tasks).
- Don't auto-create. Confirm the parsed type, title, and tags inline before writing the file. One sentence is enough: "Saving as fact note
2026-05-02_fact_supabase-rls-pattern.md with tags #supabase #postgres. Go?"
Procedure
Always step 1: Confirm or determine the type
Triggered by: "note this", "save this", "take a note", "meeting notes for X", "idea:", "fact:", "/notes ".
Parse the trigger:
- "meeting notes for X" / "from my meeting" →
meeting
- "idea:" / "I just thought of" / "what if" →
idea
- "fact:" / "save this:" / "tidbit:" / "remember that" →
fact
- Ambiguous → ASK: "Meeting note, idea, or fact?"
2a. Capture a meeting note
- If you have a calendar tool wired up (an MCP server that can list today's events), call it for today's events and present them as a numbered list with time + summary + attendees:
Today's meetings:
1. 9:00 AM - 1:1 with Sam (Sam)
2. 11:00 AM - Acme Corp sync (Taylor, Jordan)
3. 2:00 PM - Team standup (Morgan, Casey)
Which meeting is this for? (or 'none')
If no calendar tool is available, skip straight to asking for the meeting title and attendees.
- Wait for the user's pick.
- On a number: prefill
title from event summary, people from the attendee firstnames (lowercase). Suggest tags from common patterns (e.g. attendee firstnames → #firstname).
- On "none": ask for title + attendees manually.
- Capture body. If the user gave the body inline ("meeting notes for the Sam 1:1: discussed onboarding..."), use that. Otherwise prompt: "What did you discuss?"
- Confirm filename + frontmatter inline. Write with the
Write tool.
- Confirm path back: "Saved:
~/work/notes/2026-05-02_meeting_1on1-with-sam.md"
2b. Capture an idea note
- The body is usually inline ("idea: notes skill should also handle..."). Use everything after the trigger word as the body.
- Generate a 2-4 word slug from the body (lowercase, hyphens). Show it: "Slug:
notes-skill-search. Different?"
- Suggest tags from obvious nouns/projects in the body. Confirm.
- Write the file. Confirm path.
2c. Capture a fact note
Facts are the highest-value-to-find category. Push for tags.
- Body is usually inline ("fact: postgres RLS policies cascade through views..."). Use everything after the trigger as body.
- Ask for a topic slug if not obvious from the first sentence: "Topic slug? (e.g.
postgres-rls-cascade)"
- Always ask for at least one tag. Facts without tags rot. Suggest tags from the body's nouns; the user can accept or replace.
- Write the file. Confirm path.
3. Find notes (search)
Triggered by: "find notes about X", "what did I write down about Y", "search my notes", "/notes find ".
Default search scope is the entire notes root (~/work/notes/ or your NOTES_DIR, and any sibling folders you keep under the same parent, like saved emails or briefs). The user may want to find anything they've saved, not just notes.
- Use ripgrep across the notes root:
Bash: rg -i --type md -l "<query>" "$HOME/work/"
- For each hit, also pull a one-line preview (first non-frontmatter line containing the match).
- Present numbered:
Hits (5):
1. ~/work/notes/2026-05-02_fact_supabase-rls.md - "RLS policies cascade through views..."
2. ~/work/notes/2026-04-28_meeting_1on1-with-sam.md - "discussed onboarding..."
3. ~/work/email/saved/2026-04-15_taylor_q3-numbers.md - (subject line)
...
- End with: "Open a number to read it, or refine."
- On "open 1" / "1" →
Read the file and surface contents.
Filter flags (optional, parse from query):
type:meeting / type:idea / type:fact → restrict glob to *_<type>_*.md in ~/work/notes/
since:YYYY-MM-DD → filter results by filename date prefix
for:#tag → grep for the tag in frontmatter or body
from:<sender> → match email saves where frontmatter from: includes the value
4. List notes by type
Triggered by: "show meeting notes", "show ideas from this week", "show facts", "/notes list type:".
- Glob
~/work/notes/*_<type>_*.md.
- Apply date filter if given (
since: or "this week" → past 7 days).
- Sort by filename date descending.
- Show numbered: date + title + tags.
- End with: "Open a number to read it."
5. Facts view (browse by tag)
Triggered by: "show facts", "/notes facts", "what facts do I have about X".
Facts accumulate forever. This view groups them by tag for browsing.
- Glob
~/work/notes/*_fact_*.md.
- For each, parse frontmatter
tags.
- Group by tag. A fact with multiple tags appears under each (don't dedupe - browsing benefit > listing tidiness).
- Format:
FACTS (12 total)
#postgres (3)
1. 2026-05-02 - RLS policies cascade through views
2. 2026-04-30 - Window functions can't reference aliases in the same SELECT
3. 2026-04-12 - pg_stat_statements needs preload
#acme-corp (2)
4. 2026-04-28 - They use Salesforce, not HubSpot
5. 2026-03-15 - Decision-maker is the COO, not the CIO
Untagged (1)
6. 2026-04-01 - ...
- End with: "Open a number to read, or filter by tag."
If a fact has no tags, group under Untagged and surface count prominently - that's a flag the user should fix.
6. Open / read a note
Triggered by: "open #N", "show me the X note", "read note 3".
Read the file. Surface its contents. Offer: "Edit, append, or done?"
7. Edit / append
Triggered by: "add to that note", "append:", "edit note 3".
Read then Edit. Same pattern as /tasks. For meeting notes especially, appending follow-ups is common ("discussed today: ..."). Just append below existing body, with a date subhead if the new content is from a different day:
## 2026-05-09 follow-up
- Sam confirmed the timeline
- Need to circle back with Taylor
8. Delete a note
Triggered by: "delete note 3", "remove the X note".
Confirm exact filename + first line. On verbatim approval, delete the file. Don't move to a trash folder - the user has git history if they need recovery.
Email integration (optional)
If you also use an email-triage workflow that can call this skill ("note from this email"):
- The caller passes: type, sender (suggested tag), msg_id, subject, optional body snippet.
- Set
source: email msg:<id> in frontmatter.
- Suggest the sender's firstname (or domain shortname) as a tag.
- Body should include a 2-3 line quoted excerpt from the email + the user's own commentary.
- Confirm and write.
This lets the user later /notes find and pull both the note and (via the source: link) the original email back, if you have a tool that can fetch email by id.
When to ASK vs DECIDE
- Ask: ambiguous type (meeting vs idea vs fact), missing topic slug for a fact, person tags not explicit, "which meeting" for a meeting note.
- Decide: clear type from trigger word, slug obvious from body, tags only if the body literally says "#tag".
What this skill does NOT do
- No automatic tagging based on guessing - the user's tags are the user's tags.
- No external sync (Notion, Obsidian, etc.) - markdown files only.
- No mobile capture - notes added via Claude Code session or by editing files directly.
- No auto-summarization of long notes - store what the user wrote.
- No reminders / time-based surfacing - pair with a scheduler skill for digests, if you have one.
- No index file (
NOTES.md) - pure filename + frontmatter + grep. Indexes drift.
1---2name: notes3description: Capture and find notes. Three types: meeting (notes from a specific meeting), idea (something to think about later), fact (a tidbit to remember). All notes save to a notes folder (default `~/work/notes/`, see Storage below) with required frontmatter and consistent filenames so search actually works. Search runs across the whole notes root (notes, and anything else you keep under that same folder, like saved emails or briefs). Use when asked to "take a note", "note this", "save this idea", "save this fact", "meeting notes for...", "find my notes about...", "what did I write down about...", "show meeting notes", "show ideas", "show facts", or invoked as /notes. Also surfaces for natural phrases like "I should write this down" or "remind me of this".4---56# Notes78Personal notes. Three types, all stored as individual markdown files with required frontmatter for findability.910## Storage1112- **Root folder:** `~/work/notes/` by default. To use a different folder, set the environment variable `NOTES_DIR` before starting Claude Code, and swap `~/work/notes/` for `$NOTES_DIR` everywhere in this file.13- **Filename:** `YYYY-MM-DD_<type>_<topic-slug>.md`14 - Type is one of: `meeting`, `idea`, `fact`15 - Slug: lowercase, hyphens, no punctuation, max ~50 chars16 - Examples:17 - `2026-05-02_meeting_1on1-with-sam.md`18 - `2026-05-02_idea_notes-skill-design.md`19 - `2026-05-02_fact_supabase-rls-pattern.md`20- **Frontmatter (required, every note):**21 ```yaml22 ---23 type: meeting | idea | fact24 date: 2026-05-0225 title: short human title26 tags: [#sam, #acme-corp] # optional, lowercase #word27 people: [sam, taylor] # meeting notes only - short names, lowercase28 source: email msg:<id> | conversation | link:<url> | null29 ---30 ```31- **Body:** free-form markdown.3233## Hard rules3435- **Always include the full frontmatter block.** Missing fields make notes unfindable later.36- **Filename strict format.** `YYYY-MM-DD_<type>_<topic-slug>.md`. No exceptions. Date is today's date from the system context (absolute, never "today" / "Friday").37- **Type is one of three.** `meeting`, `idea`, `fact`. If the user is ambiguous, ASK. Don't invent a fourth type.38- **Don't auto-tag people.** If the user mentions a person without explicitly tagging, ask before adding `#person` (same pattern as `/tasks`).39- **Don't auto-create.** Confirm the parsed type, title, and tags inline before writing the file. One sentence is enough: *"Saving as fact note `2026-05-02_fact_supabase-rls-pattern.md` with tags `#supabase #postgres`. Go?"*4041## Procedure4243### Always step 1: Confirm or determine the type4445Triggered by: "note this", "save this", "take a note", "meeting notes for X", "idea:", "fact:", "/notes <body>".4647Parse the trigger:48- "meeting notes for X" / "from my meeting" → `meeting`49- "idea:" / "I just thought of" / "what if" → `idea`50- "fact:" / "save this:" / "tidbit:" / "remember that" → `fact`51- Ambiguous → ASK: "Meeting note, idea, or fact?"5253### 2a. Capture a meeting note54551. If you have a calendar tool wired up (an MCP server that can list today's events), call it for today's events and present them as a numbered list with time + summary + attendees:56 ```57 Today's meetings:58 1. 9:00 AM - 1:1 with Sam (Sam)59 2. 11:00 AM - Acme Corp sync (Taylor, Jordan)60 3. 2:00 PM - Team standup (Morgan, Casey)6162 Which meeting is this for? (or 'none')63 ```64 If no calendar tool is available, skip straight to asking for the meeting title and attendees.652. **Wait for the user's pick.**66 - On a number: prefill `title` from event summary, `people` from the attendee firstnames (lowercase). Suggest tags from common patterns (e.g. attendee firstnames → `#firstname`).67 - On "none": ask for title + attendees manually.683. Capture body. If the user gave the body inline ("meeting notes for the Sam 1:1: discussed onboarding..."), use that. Otherwise prompt: "What did you discuss?"694. Confirm filename + frontmatter inline. Write with the `Write` tool.705. Confirm path back: *"Saved: `~/work/notes/2026-05-02_meeting_1on1-with-sam.md`"*7172### 2b. Capture an idea note73741. The body is usually inline ("idea: notes skill should also handle..."). Use everything after the trigger word as the body.752. Generate a 2-4 word slug from the body (lowercase, hyphens). Show it: *"Slug: `notes-skill-search`. Different?"*763. Suggest tags from obvious nouns/projects in the body. Confirm.774. Write the file. Confirm path.7879### 2c. Capture a fact note8081Facts are the highest-value-to-find category. Push for tags.82831. Body is usually inline ("fact: postgres RLS policies cascade through views..."). Use everything after the trigger as body.842. Ask for a topic slug if not obvious from the first sentence: *"Topic slug? (e.g. `postgres-rls-cascade`)"*853. **Always ask for at least one tag.** Facts without tags rot. Suggest tags from the body's nouns; the user can accept or replace.864. Write the file. Confirm path.8788### 3. Find notes (search)8990Triggered by: "find notes about X", "what did I write down about Y", "search my notes", "/notes find <query>".9192**Default search scope is the entire notes root** (`~/work/notes/` or your `NOTES_DIR`, and any sibling folders you keep under the same parent, like saved emails or briefs). The user may want to find anything they've saved, not just notes.93941. Use ripgrep across the notes root:95 ```96 Bash: rg -i --type md -l "<query>" "$HOME/work/"97 ```982. For each hit, also pull a one-line preview (first non-frontmatter line containing the match).993. Present numbered:100 ```101 Hits (5):102 1. ~/work/notes/2026-05-02_fact_supabase-rls.md - "RLS policies cascade through views..."103 2. ~/work/notes/2026-04-28_meeting_1on1-with-sam.md - "discussed onboarding..."104 3. ~/work/email/saved/2026-04-15_taylor_q3-numbers.md - (subject line)105 ...106 ```1074. End with: *"Open a number to read it, or refine."*1085. On "open 1" / "1" → `Read` the file and surface contents.109110**Filter flags** (optional, parse from query):111- `type:meeting` / `type:idea` / `type:fact` → restrict glob to `*_<type>_*.md` in `~/work/notes/`112- `since:YYYY-MM-DD` → filter results by filename date prefix113- `for:#tag` → grep for the tag in frontmatter or body114- `from:<sender>` → match email saves where frontmatter `from:` includes the value115116### 4. List notes by type117118Triggered by: "show meeting notes", "show ideas from this week", "show facts", "/notes list type:<t>".1191201. Glob `~/work/notes/*_<type>_*.md`.1212. Apply date filter if given (`since:` or "this week" → past 7 days).1223. Sort by filename date descending.1234. Show numbered: date + title + tags.1245. End with: *"Open a number to read it."*125126### 5. Facts view (browse by tag)127128Triggered by: "show facts", "/notes facts", "what facts do I have about X".129130Facts accumulate forever. This view groups them by tag for browsing.1311321. Glob `~/work/notes/*_fact_*.md`.1332. For each, parse frontmatter `tags`.1343. Group by tag. A fact with multiple tags appears under each (don't dedupe - browsing benefit > listing tidiness).1354. Format:136 ```137 FACTS (12 total)138139 #postgres (3)140 1. 2026-05-02 - RLS policies cascade through views141 2. 2026-04-30 - Window functions can't reference aliases in the same SELECT142 3. 2026-04-12 - pg_stat_statements needs preload143144 #acme-corp (2)145 4. 2026-04-28 - They use Salesforce, not HubSpot146 5. 2026-03-15 - Decision-maker is the COO, not the CIO147148 Untagged (1)149 6. 2026-04-01 - ...150 ```1515. End with: *"Open a number to read, or filter by tag."*152153If a fact has no tags, group under `Untagged` and surface count prominently - that's a flag the user should fix.154155### 6. Open / read a note156157Triggered by: "open #N", "show me the X note", "read note 3".158159`Read` the file. Surface its contents. Offer: *"Edit, append, or done?"*160161### 7. Edit / append162163Triggered by: "add to that note", "append:", "edit note 3".164165`Read` then `Edit`. Same pattern as `/tasks`. For meeting notes especially, appending follow-ups is common ("discussed today: ..."). Just append below existing body, with a date subhead if the new content is from a different day:166```markdown167## 2026-05-09 follow-up168- Sam confirmed the timeline169- Need to circle back with Taylor170```171172### 8. Delete a note173174Triggered by: "delete note 3", "remove the X note".175176Confirm exact filename + first line. On verbatim approval, delete the file. Don't move to a trash folder - the user has git history if they need recovery.177178## Email integration (optional)179180If you also use an email-triage workflow that can call this skill ("note from this email"):1811821. The caller passes: type, sender (suggested tag), msg_id, subject, optional body snippet.1832. Set `source: email msg:<id>` in frontmatter.1843. Suggest the sender's firstname (or domain shortname) as a tag.1854. Body should include a 2-3 line quoted excerpt from the email + the user's own commentary.1865. Confirm and write.187188This lets the user later `/notes find` and pull both the note and (via the `source:` link) the original email back, if you have a tool that can fetch email by id.189190## When to ASK vs DECIDE191192- **Ask:** ambiguous type (meeting vs idea vs fact), missing topic slug for a fact, person tags not explicit, "which meeting" for a meeting note.193- **Decide:** clear type from trigger word, slug obvious from body, tags only if the body literally says "#tag".194195## What this skill does NOT do196197- No automatic tagging based on guessing - the user's tags are the user's tags.198- No external sync (Notion, Obsidian, etc.) - markdown files only.199- No mobile capture - notes added via Claude Code session or by editing files directly.200- No auto-summarization of long notes - store what the user wrote.201- No reminders / time-based surfacing - pair with a scheduler skill for digests, if you have one.202- No index file (`NOTES.md`) - pure filename + frontmatter + grep. Indexes drift.