Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Personal sidenote parking file (see /sidenote) — never committed
.claude/sidenotes.md
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,15 @@ Then `/scalable` (tests the current direction) or `/scalable <a specific decisio

You're mid-way through a big task and a passing thought hits — *"the retry logic probably has the same bug", "remind me to check the pricing later"* — something you don't want to forget. Drop it in the chat as-is and the agent reads it as a new request: it rushes the current task to "get to" your note, and the big task pays for it.

[`commands/sidenote.md`](./commands/sidenote.md) reframes that thought as a **parked later-task, not a now-task**. The agent logs it verbatim to `.claude/sidenotes.md` (durable across compaction and session end), gives a one-line ack, and resumes *exactly* where it was — same scope, same pace, no cutting corners to reach the note. A bare `/sidenote` flushes the list back to you.
[`commands/sidenote.md`](./commands/sidenote.md) reframes that thought as a **parked later-task, not a now-task**. The agent logs it verbatim to `.claude/sidenotes.md` (durable across compaction and session end) — with a one-line anchor (task in progress, the file it points at, branch) so it still makes sense when another session or agent reads it cold — gives a one-line ack, and resumes *exactly* where it was — same scope, same pace, no cutting corners to reach the note. A bare `/sidenote` flushes the open list back to you.

```bash
mkdir -p ~/.claude/commands
cp commands/sidenote.md ~/.claude/commands/ # personal, all projects
# or: .claude/commands/ for one project
```

Then `/sidenote <the thought>` to park one, or `/sidenote` to see what's parked. The notes land in `.claude/sidenotes.md` — add it to `.gitignore` if you'd rather not track it.
Then `/sidenote <the thought>` to park one, or `/sidenote` to see what's parked. The notes land in `.claude/sidenotes.md`, a personal parking file kept out of git (this repo's `.gitignore` already excludes it) — so it's per-checkout scratch, not shared history.

> **No slash commands?** For agents that read a rule file but have no `/` commands (Cursor, Codex, Copilot…), the same contract works as a plain-text convention: prefix the message with `SIDENOTE:` and the agent parks it instead of acting. Add one line to your rule file so it's honored reliably — see [`commands/sidenote.md`](./commands/sidenote.md) for the exact contract.

Expand Down
14 changes: 11 additions & 3 deletions commands/sidenote.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,17 @@ Park this thought — **$ARGUMENTS** — as a sidenote. A sidenote is a *later-t

**Persist it so it survives this session** (context gets compacted; memory doesn't count as "logged"):

1. Append one bullet to `.claude/sidenotes.md` at the project root — create the file (and `.claude/`) if missing.
2. Format: `- [<today's date, YYYY-MM-DD>] <the thought, captured verbatim>`. Don't paraphrase or "improve" it — capture what was said.
1. Append one entry to `.claude/sidenotes.md` at the project root — create the file (and `.claude/`) if missing.
2. Format — an open checkbox, the verbatim thought, then a one-line **anchor** so the note still makes sense when another session or agent reads it cold (the verbatim thought alone is full of "this / here / it" that dangles without the moment that produced it):

```
- [ ] [<today's date, YYYY-MM-DD>] <the thought, captured verbatim>
↳ <task you were mid-way through> · <file/area the note points at, if "this"/"here" resolves to one> · <branch>@<short-sha>
```

- **Thought — verbatim.** Don't paraphrase or "improve" it; capture what was said.
- **Anchor — coordinates you already hold, not a research task.** Fill it only from what's already in front of you: the task in progress, the file/area currently in focus, the current branch and short SHA (already in your session's git context). **Do not open files, grep, or investigate the note's subject to complete it** — that would break the park contract. Any field you don't already know, omit. The anchor records where you were standing; it never sends you looking.

Then: **one-line acknowledgement** (e.g. `Parked in .claude/sidenotes.md — continuing.`) and **resume exactly where you left off**, as if the note had never arrived.

**If `$ARGUMENTS` is empty** (a bare `/sidenote`), there's nothing to park — treat it as a *flush*: read `.claude/sidenotes.md` and list the currently-open sidenotes back to me so I can decide what to pick up. Change nothing, act on nothing, then resume.
**If `$ARGUMENTS` is empty** (a bare `/sidenote`), there's nothing to park — treat it as a *flush*: read `.claude/sidenotes.md` and list the **open** entries back to me so I can decide what to pick up. Open means *not checked off* — every entry except the ones marked done (`- [x]`), so older bullets without a checkbox still count. Change nothing, act on nothing, then resume. (Checking an item off to `- [x]` happens when it's actually handled — not part of parking or flushing.)
Loading