by cbuelo
One-way sync: editing a note's frontmatter creates or updates a matching task in Super Productivity via its local REST API.
SP Tasker
Obsidian plugin: editing a note's frontmatter creates or updates a matching task in Super Productivity, via its local REST API. One direction only — nothing syncs back from SP into Obsidian.
What it does
next(frontmatter key name configurable) becomes the task title. Accepts a string, list, number, or boolean.waiting_on(frontmatter key name configurable; string or list) prefixes the title ("Waiting on Alex: ...", or "Alex and Sam" / "Alex, Sam and Jo" for a deduped list) and adds the configured reminder tag — untagged if that tag doesn't exist yet in SP.- The note's
Project/<name>tag (frontmatter or inline body), if present, picks the SP project. The prefix (Project/by default) is configurable and can be a comma-separated list of prefixes. Only the segment directly under the matched prefix is used, soProject/WebsiteandProject/Website/v2collapse to the same project. Two different names abort the send rather than guessing. A note with no matching tag at all is created in the project named by the "Default project" setting (Inboxby default; leave it empty to let SP decide), if that project exists in SP. - Project and reminder tag both have to already exist in Super Productivity — the API is read-only for both. If a note has a project tag but SP has no matching project, the send aborts (notice) rather than silently dropping it; a missing reminder tag just sends untagged.
start(frontmatter key name configurable; optional,YYYY-MM-DD) becomes the task's due date in SP. When a task is created, astartof today or later is used, and a validstartin the past becomes today (an overdue note starts out due now, including when a new task replaces one you completed in SP); a missing or unparseablestartsends no due date. When an existing task is updated, astartstrictly in the future is sent, and astartof today is sent only if the task has no date in SP yet (for example, you addedstartto the note after the task was created). This keeps a task you've pushed to a later day in SP from being snapped back to today by an unrelated edit or a manual send. A futurestartstill overwrites a due date you set by hand in SP (Obsidian-first). A past or removedstartnever changes or clears an existing due date in SP.- Newly created tasks get no due date unless
startsupplies one (a paststartcounts as today). SP would otherwise stamp them as due today whenever its Today view is open; the "No due date on new tasks" setting (on by default) suppresses that. It only affects creation, never updates. - If a manual send is triggered on a note with no
nextvalue, a notice explains there's nothing to send (auto-triggered sends stay silent, since every keystroke touches frontmatter). - Optionally (on by default, toggleable), the task's notes field gets a clickable markdown link back to the note (
[label](obsidian://open?vault=...&file=...)), since SP only auto-linkifies http/https, not theobsidian:scheme. - The plugin never overwrites notes you typed yourself in SP — only an empty field, a bare
obsidian://open?...(old format), or its own current link format gets replaced. sp_task_idandsp_task_refare written back into the note's frontmatter by the plugin.sp_task_refis the note's permanent display number: once assigned it's read from the note itself rather than internal state, so it can't drift or get reassigned ifdata.jsonis ever lost. It only changes if the task it spawned in SP gets checked and then next gets changed. Then, a new task is created with a new ref string, but same ID# (because it comes from the same note).- A successful send shows a brief confirmation notice.
Runs automatically (debounced, 250ms floor) whenever a note's frontmatter changes or the note is renamed, or immediately via the Send current note to Super Productivity command — which also force-resyncs even when nothing changed, and re-checks the task's live status in SP.
Requirements
- Super Productivity desktop v14+, with the local REST API enabled (Settings → Misc, off by default) and its access token, listening on
http://127.0.0.1:3876. - Obsidian desktop — the API is bound to
127.0.0.1, so this only works with both apps running on the same machine.
Install
Download main.js and manifest.json from the latest release and copy them into <vault>/.obsidian/plugins/sp-tasker/, then enable the plugin in Obsidian and set the API URL/token in its settings tab.
If updating the plugin, just drop the new main.js and manifest.json into the plugin directory, data.json stays the same and you won't have to re-enter your SP API token.
You can also install it through BRAT using this repository's URL.
Network use and privacy
- Network: the plugin's only network traffic is HTTP requests to the Super Productivity (SP) local REST API at the URL set in its settings (default
http://127.0.0.1:3876, i.e. SP running on your own machine). It reads and writes tasks, projects and tags there. If you point the URL somewhere else, requests go to that address instead. Nothing is sent to any other server. - Access token: the SP access token you enter is sent as a
Bearertoken to that API URL, and is stored unencrypted in the plugin'sdata.jsoninside your vault (<vault>/.obsidian/plugins/sp-tasker/). Keep that in mind if you sync or share your vault. - Account / payment: none. Super Productivity is a separate, free app that must be installed and running on the same machine.
- Telemetry and ads: none.
- Files: the plugin only reads notes in your vault (frontmatter and tags) and writes
sp_task_id/sp_task_refinto the frontmatter of notes it syncs. It does not access files outside your vault. Once at startup it also checks every note's cached frontmatter (not the note text) for the highestsp_task_ref, so the plugin's ref counter can never fall behind numbers already written into your notes. Nothing from that scan is stored or sent anywhere. - Source and license: open source under the MIT license.
Idempotency
Every send computes two signatures for the note: content (title, resolved project name, resolved tag name, plus the due date when start supplies one) and full (content + the note's vault path), joined with a \x01 separator and stored per SP task id.
- Auto-triggered sends return early when the
fullsignature is unchanged. The manual command never short-circuits this way — it always re-checks the task with SP. - If only the path changed (content signature still matches), the plugin refreshes the notes link and does nothing else — this is what stops a rename from reopening a completed task.
- Otherwise it fetches the task from SP: if it's still open, that task is PATCHed in place and keeps its existing
sp_task_ref. If it's done, archived, or gone (404), a brand-new task is created instead, with a new sequentialsp_task_ref.
If the plugin's data.json is lost, its ref counter can't restart at 1 and collide with numbers already written into the vault: on every startup (layout-ready) it automatically rescans all notes and raises the counter above the highest sp_task_ref found. It can't recover the old SP task ids though, so notes touched after data.json is lost will get a new task rather than update their old one.
Errors and warnings surface only as an Obsidian Notice plus console.error. Log view may be added in future.
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.