Directives: live panels in notes
Notes can embed directives — :grove-* syntax that renders as a live React panel inside the markdown and round-trips back to the exact source on save. A note stops being static prose and becomes a live view onto your tasks, agents, comments, and PRs: a daily log with a real kanban board in it, a project plan whose task pills show live state.
Quick reference
| Directive | Form | What it shows |
|---|---|---|
:grove-task[<task>] |
inline | live pill for a task — dot + name + state; click opens its agent chat |
::grove-task[<task>]{desc=…} |
block | the full task card: agent pill, branch + worktree, PR (open or create), refresh / merge / archive |
::grove-agents{filter=…} |
block | fleet dashboard of running agents with comment counts |
::grove-query{kind=comments status=open …} |
block | filtered comment list (read-only) |
::grove-refs{symbol=…} |
block | a symbol's uses across code and notes |
::grove-backlinks |
block | notes linking to the current note |
::grove-reviews |
block | PRs awaiting your review — open each as a Grove review task |
::grove-github{issues} / {prs} |
block | live GitHub issue / PR list for the repo |
::grove-github{issue=N} / {pr=N} |
block | a single GitHub issue / PR card |
:::grove-board … ::: |
container | kanban board built from the body markdown |
Syntax
Three forms, all sharing an optional [label] and {key=value} attributes:
- Inline —
:name[label]{k=v}— flows inside a paragraph (pills, buttons). - Leaf block —
::name{k=v}— a standalone panel on its own line. - Container block —
:::name{k=v}…:::— a panel that operates on a chunk of markdown.
The slash menu (/) inserts any of them with correct syntax, and agents can author them too — the MCP server exposes the directive catalog as a tool, so an agent writing a status note can drop in a working board. See MCP.
The task directive
:grove-task names one unit of work and carries everything about it. The inline : form is a compact pill; the block :: form is the full card.
task=(or the[label]) — the task, resolved by slug or name.desc=— a one-line description under the card head.chat=— link a specific Grove chat; the agent pill resumes that exact session. With nochat=, the pill is a "Start chat" launcher that mints a chat and writeschat=<id>back into your note, so re-clicking resumes it.session=— link a raw Claude/Codex session id instead of a Grove chat.pr=— pin an explicit PR. Omit it and the card resolves the PR from the task's branch — opening it if one exists, or offering Create PR if not.
The board
:::grove-board reads its body as the board: ## Heading becomes a column, - card / - [ ] card become cards.
:::grove-board
## To Do
- wire the parser
## Doing
- [ ] write the panel
## Done
- [x] schema nodes
:::
Drag cards between columns, toggle checkboxes, add or delete cards and columns — each edit rewrites the body markdown in place, so the raw view always shows the current state. The board is the markdown.
Behavior you can rely on
- Round-trip safe. A directive survives the WYSIWYG → disk auto-save unchanged. Unknown or misspelled
grove-*names render as a visible dashed chip and still round-trip — nothing is silently dropped. - Prose-safe. Ordinary colons (
foo:bar,std::vector,src/x.ts:42) are never treated as directives. Only thegrove-prefix is. - Actions confirm first. A directive's mutating actions (rebase, squash-merge, archive, create-PR) require an explicit click, and the destructive ones confirm — pasting a directive into a note never auto-triggers anything.
- GitHub directives are read-only and ride your
ghCLI login — no separate token. Filters:state,label,assignee,limit.
Filters
grove-query:status(open/resolved/all),task,file(path substring),tag(body substring),limit.grove-agents: omit (orlive) for agents actually running/waiting/blocked,allfor every active task, or a single state name.
See also
- Markdown editor — the surface directives render in.
- Starter templates — pre-built notes that ship with working directives.