# โœ… Nextcloud Tasks for Obsidian Read, create, edit and complete your **Nextcloud Tasks** right inside a note โ€” over CalDAV, with no copy of your data in the vault.

A task panel in a note: two lists with headings and colours, due dates, priority flags, a '+3 more' line and a blank row to type a new task into

--- ## ๐Ÿง  The one idea **There is exactly one copy of every task, and it lives in Nextcloud.** Other CalDAV plugins mirror markdown checkboxes into your notes and sync them โ€” two copies, forever at risk of drifting apart. This one writes nothing to disk, not even a cache: it fetches, shows, and writes your change straight back.

Flow: a note's code block and the plugin settings feed the plugin, which holds tasks in memory only and talks to Nextcloud with PROPFIND/REPORT to read and PUT/DELETE to write

Plain JavaScript, no dependencies, no native code โ€” the same build runs on desktop and phone. ๐Ÿ“ฑ --- ## ๐Ÿš€ Install & set up **From Obsidian:** *Settings โ†’ Community plugins โ†’ Browse*, search **Nextcloud Tasks**, install, enable. **Manually:** drop `main.js`, `manifest.json` and `styles.css` from the [latest release](https://github.com/JUNSKIx1/obsidian-nextcloud-tasks/releases/latest) into `/.obsidian/plugins/nextcloud-tasks/`, then enable it under *Settings โ†’ Community plugins*. | # | Step | | | --- | --- | --- | | 1๏ธโƒฃ | **Make an app password** in Nextcloud โ†’ *Settings โ†’ Security* | Never your account password. It can be revoked on its own, and it is the only credential stored. | | 2๏ธโƒฃ | **Fill in the settings** in Obsidian โ†’ *Nextcloud Tasks* | Address is the base only: `https://cloud.example.com`, **not** `/remote.php/dav`. | | 3๏ธโƒฃ | **Press Load** | Every list on your account appears. Tick the ones you want, rename the headings, pick colours, drag them into order. No list yet? **Create list** makes one on the server. | | 4๏ธโƒฃ | **Set the refresh interval** | 5 minutes by default, **Never** if you prefer by hand. It only runs while a task list is on screen, so it costs nothing while you write. | | 5๏ธโƒฃ | **Stuck? Press Test connection** | It reports every discovery step separately, so a failure points at one line instead of "could not connect". | > ๐Ÿท๏ธ **Any lists, any names.** No fixed categories, no folder convention. Each list you tick gets a > heading, a colour and a short **key** โ€” the key is what a note refers to. Two lists or nine, in > whatever order you drag them, is all the same to the plugin. --- ## ๐Ÿ“ Show tasks in a note ````markdown ```nextcloud-tasks all preview: 3 ``` ```` Every ticked list gets its own heading, even when empty. Past `preview:` rows, the heading grows an arrow and the number it is holding back โ€” click to unfold, click to fold away. Each list ends in a **blank row**: type a title, press Enter, and the task is on the server. The two small buttons on that row set a due date and a priority first; Esc clears it. Nothing you type is lost to a background refresh. โœ๏ธ Every line inside the block is optional: | Line | What it does | | --- | --- | | `all` *(or an empty block)* | ๐Ÿ“š every ticked list, grouped by list โ€” **the default** | | `list: errands` | ๐Ÿ“‹ one list only, by its key (`os:` still works in old notes) | | `preview: 3` | ๐Ÿ‘๏ธ rows per list before the **+n more** line; `preview: 0` shows everything | | `limit: 8` | โœ‚๏ธ hard ceiling on rows **in total**, applied before lists are split โ€” a busy list can eat it all, so `preview` is usually what you want | | `due: today` | ๐Ÿ“… due today โ€” **overdue is always included**, or it would vanish silently | | `due: week` | ๐Ÿ—“๏ธ due within seven days, overdue included | | `done: true` | โ˜‘๏ธ show completed tasks too | | `title: Shopping` | ๐Ÿท๏ธ your own heading for the panel | German values (`due: heute`, `due: woche`, `done: ja`) are accepted, so a note keeps its meaning if you switch Obsidian's language. Rows sort the way you would triage them: **overdue first**, then by due date, undated last, ties falling back to your list order. The panel header carries โž• new task, ๐Ÿ“‹ new list and โ†ป refresh. --- ## ๐Ÿ‘† Working with a task - **โ˜‘๏ธ Tick the box** to complete it โ€” written to the server immediately. The row stays on screen with a line through it until you leave the note, so you can see what you did and undo a misclick. - **โœ๏ธ Click the title** to edit title, due date and priority. Only what you actually changed is written, so a repeat rule, reminder, description or subtask the plugin doesn't show stays untouched. *(Moving a task to another list happens in Nextcloud, not here.)* - **๐Ÿ—‘๏ธ Delete** lives in the same dialog, behind one confirmation. **Commands:** `New task` ยท `Refresh tasks` ยท `Test connection`. --- ## ๐Ÿ“ฑ On your phone Add a CalDAV account with the same address, username and app password to your phone's built-in reminders app: notifications and widgets without Obsidian running, and anything you tick there shows up here on the next refresh. The plugin itself also runs in the Obsidian mobile app. ๐ŸŒ **Languages:** English and German, following Obsidian's setting (or forced in the plugin settings). --- ## ๐Ÿ› ๏ธ Development ```bash npm install npm run lint # eslint-plugin-obsidianmd โ€” the rules the directory review runs npm test # core, render and bundle suites: no install, no network, no credentials npm run build # bundles src/ into main.js ``` ```bash VAULT="/path/to/your/vault" bash scripts/deploy-to-vault.sh # deploy a local build NC_URL=https://cloud.example.com NC_USER=alice NC_APP_PASSWORD=xxxxx \ node scripts/live-check.mjs # against a real server ``` `live-check` creates, reads, completes and deletes one test task: it proves the *server* speaks CalDAV, not that your device passes the verbs through โ€” that's what **Test connection** is for. โš ๏ธ `main.js` is generated. Edit `src/`, never the bundle.
๐Ÿ” Design notes โ€” things that look like details and are not - **Nothing is written to disk, not even as a cache.** The fetched list lives in memory for the session. That is what makes "your tasks live in Nextcloud" literally true, and why there is no file that can go stale. - **Completing or editing rewrites the original calendar object line by line**, copying every other byte through. Regenerating from a parsed model would silently drop `RRULE`, `VALARM`, `CATEGORIES`, `RELATED-TO` and every `X-` property other clients wrote. The tests assert byte identity of untouched lines, for both writers. - **An edit sends only the fields you changed.** Leaving the date alone differs from clearing it: the first never mentions `DUE`, so a task due at a particular time keeps that time when you fix a typo in its title. The second removes the line. - **Completion is judged in the client**, because three clients express it three ways: `STATUS`, a bare `COMPLETED:`, or `PERCENT-COMPLETE:100`. A server-side filter that gets this wrong hides tasks, which is worse than showing one too many. - **Priority follows RFC 5545** โ€” 1 is most urgent, 0 unset: 1โ€“4 high, 5 medium, 6โ€“9 low, each with a coloured flag. Flagging only the top band is what made an earlier version look broken. - **Discovery walks the real chain**, `current-user-principal` โ†’ `calendar-home-set` โ†’ the collections in it, instead of guessing `/remote.php/dav/calendars//`. Fifteen lines, and a whole class of username-casing bug disappears. - **XML is read without caring about namespace prefixes.** Nextcloud's `d:` and `cal:` are not contractual. - **If `REPORT` is refused**, the client falls back to `PROPFIND` plus one `GET` per object and remembers that for the session, so a platform blocking the verb still works. - **Everything goes through `requestUrl`**, which bypasses CORS and works on iOS.
--- ๐Ÿ“„ MIT โ€” see [LICENSE](LICENSE).