grove

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 no chat=, the pill is a "Start chat" launcher that mints a chat and writes chat=<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 the grove- 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 gh CLI 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 (or live) for agents actually running/waiting/blocked, all for every active task, or a single state name.

See also