Linear Agenda
unlistedby Arjun Ray
Pull Linear issues into notes as templated, snapshotted agendas with configurable due-date gates.
Linear Agenda
An Obsidian plugin that pulls your Linear issues into a note once, as a templated checklist, and then leaves them alone.
The point is the "leaves them alone" part. Most integrations render a live query, so opening a daily note from three weeks ago shows you today's work. This one writes a snapshot into the note the first time the block renders. After that the note is a record of what that day actually looked like, and it only changes when you press refresh.
Works on desktop and mobile.
What it does
- Due date gates. Issues are bucketed into sections: due today, due this week, and any further gate you want to add (due this month, overdue, no due date, due in the next 14 days). Gates are ordinary settings, not code.
- Snapshots, not live queries. The block stores the issues and which gate each one fell into. Reopening the note re-reads that, so yesterday's agenda stays yesterday's agenda.
- Nested sub-issues. Children sit under their parents. A parent that did not match the gate is still shown, greyed out, so a lone sub-issue keeps its context.
- Configurable rows. Tick which fields each row shows, or write the row template yourself.
- Optional write-back. Off by default: rows are inert checklist items that never touch Linear. Turn it on and ticking a box completes the issue, and each row gets an editor for status, priority, due date, estimate, and title.
Installing
The plugin is not in the community list yet, so pick one of these.
With BRAT (easiest, and the only easy path on mobile)
- Install Obsidian42 - BRAT from Community plugins.
- Open BRAT's settings and choose Add beta plugin.
- Paste
deconstructionalism/obsidian-linear-agenda. - Enable Linear Agenda under Community plugins.
BRAT reads the latest GitHub release, so this works identically on desktop, iOS, and Android. See docs/MOBILE.md for testing unreleased work on a phone.
By hand
Download main.js, manifest.json, and styles.css from the
latest release
and drop them into <your vault>/.obsidian/plugins/linear-agenda/. Restart
Obsidian and enable the plugin.
From source
git clone https://github.com/deconstructionalism/obsidian-linear-agenda.git
cd obsidian-linear-agenda
npm install
npm run build
Copy main.js, manifest.json, and styles.css into the plugin folder above.
npm run dev rebuilds on save if you are working on it.
Setting it up
- Create a personal API key in Linear under Settings, Security and access, Personal API keys.
- Paste it into the plugin settings and press Test. It should greet you by name.
- Put an agenda block into a note, or into your daily note template:
```linear-agenda
```
That is a complete block. The first time it renders it fetches your issues, writes them into itself, and never fetches again unless you press refresh.
The block
The block has two halves separated by a --- line. You write the top half; the
plugin writes the bottom half.
```linear-agenda
gates: due-today, due-this-week
title: Today
teams: ENG
---
{"version":1,"generatedAt":"2026-08-01T09:00:00.000Z", ... }
```
| Option | Meaning |
|---|---|
gates | Which gates to show, in order. Defaults to every enabled gate. |
title | A heading above the whole agenda. |
teams | Team keys to restrict every gate to, such as ENG, OPS. |
assignee | me, anyone, or unassigned. Overrides the gates. |
date | Pin the agenda to a calendar day rather than the day it renders. |
frozen | Never re-fetch automatically, whatever the refresh policy says. |
Naming a gate in gates turns it on for that block even when settings have it
switched off, which is how you get one note that also shows a month view.
Daily notes
Put the block in your daily note template. The template fires when the note is created, the block fetches once, and from then on that note holds that day's list. Tomorrow's note gets tomorrow's list.
With Templater you can pin each note to its own date, which matters if you create a daily note late or backfill one:
```linear-agenda
date: <% tp.date.now("YYYY-MM-DD") %>
title: <% tp.date.now("dddd") %>
```
Gates
A gate is a due date rule plus filters plus a sort. The shipped gates are:
| Gate | Rule | On by default |
|---|---|---|
| Due today | Due on or before today, including overdue | Yes |
| Due this week | Due on or before the end of this week | Yes |
| Due this month | Due on or before the end of this month | No |
| No due date | Carries no due date | No |
By default an issue lands in the first gate it fits, so widening gates read as one list rather than repeating the same issue three times. Switch that to "every matching gate" in settings if you want overlapping views.
Full reference: docs/GATES.md.
Rows
Tick the fields you want in settings and the row template is generated for you. Turn on Write the row template by hand for full control:
[{{identifier}}]({{url}}) {{title}}{{#if state}} · {{state}}{{/if}}{{#if dueRelative}} · due {{dueRelative}}{{/if}}
Conditionals mean an absent value takes its separator with it, so rows never end up with a trailing dot. Full token list: docs/TEMPLATES.md.
Templates are applied at render time, not at fetch time, so changing one reflows every note you have already written. The issues stay frozen; only the formatting moves.
Writing back to Linear
Off by default. While it is off, a checkbox is just a checkbox: ticking it marks the row done in the note and Linear never hears about it.
Turn on Allow edits to write back to Linear and:
- Ticking a checkbox moves the issue into a completed status.
- Each row gets a pencil that opens an editor.
- The editor shows only the fields you enable: status, priority, due date, estimate, title.
Edits update the snapshot in place, so a status change does not sweep in issues created since the snapshot was taken.
Commands
| Command | What it does |
|---|---|
| Insert Linear agenda | Drops an empty block at the cursor. |
| Insert Linear agenda pinned to today | Same, with today's date baked in. |
| Refresh Linear agendas in this note | Re-fetches every agenda in the current note. |
Developing
npm install
npm run dev # watch build
npm run test # vitest
npm run verify # types, lint, styles, format, tests
npm run fix # format and autofix
A pre-commit hook formats and lints staged files; a pre-push hook typechecks and runs the tests. CI runs all of it on every push and pull request.
Pushing a tag that matches manifest.json cuts a release with the three plugin
files attached, which is what BRAT installs from.
npm version minor # bumps package.json, manifest.json, versions.json
git push --follow-tags
Licence
MIT. See LICENSE.
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.