Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
14edea4
move OAuth secrets to Secret Storage
mcuste Jul 11, 2026
3811efc
fix: record real completion date on materialized occurrences
raphaelfaouakhiri Jul 17, 2026
354a568
feat: add occurrence filename template variables (#2126)
raphaelfaouakhiri Jul 17, 2026
3365081
feat: settings and UI for occurrence filename template (#2126)
raphaelfaouakhiri Jul 17, 2026
55c336a
feat: name materialized occurrences from configurable template (#2126)
raphaelfaouakhiri Jul 17, 2026
bf3a12d
fix(bases): keep Task List groups collapsed on first render
renatomen Jul 28, 2026
84513f6
Fix recurring all-day ICS event end dates (#1958)
abbiefalls90 Jul 31, 2026
a166b3c
Fix Kanban hide-empty columns with swimlanes (#2019)
scottTomaszewski Jul 31, 2026
4215f2f
Fix project folder badge subtask toggle (#2033)
abbiefalls90 Jul 31, 2026
39c42b4
Avoid Google Calendar retry queue when sync is disabled (#2041)
chmac Jul 31, 2026
c545c68
Focus natural-language date input when enabled (#2051)
ther12k Aug 1, 2026
1e7c8f8
Fix dynamic recurring schedule advancement (#2066)
chmac Aug 1, 2026
a02ce2b
Fix reading mode note widget stability (#2103)
martin-forge Aug 1, 2026
b5a6263
Add project folder template variables (#2105)
carypruitt Aug 1, 2026
ca64515
Address OAuth secret storage review findings
callumalpass Aug 1, 2026
ceeab4b
Merge remote-tracking branch 'origin/main' into agent/pr-2112-merge
callumalpass Aug 1, 2026
41b123e
Merge pull request #2112 from mcuste/feat/oauth-secret-storage
callumalpass Aug 1, 2026
ca4c540
Merge remote-tracking branch 'origin/main' into pr-2129
callumalpass Aug 1, 2026
8dc8b86
docs: add completion date fix to unreleased
callumalpass Aug 1, 2026
e8b44c4
Merge pull request #2129 from raphaelfaouakhiri/patch/real-completed-…
callumalpass Aug 1, 2026
94a5d30
Merge remote-tracking branch 'origin/main' into pr-2134
callumalpass Aug 1, 2026
1499818
fix: make occurrence filename templates explicit
callumalpass Aug 1, 2026
004764d
Merge pull request #2134 from raphaelfaouakhiri/patch/occurrence-file…
callumalpass Aug 1, 2026
f4a7cc7
Merge remote-tracking branch 'origin/main' into pr-2166
callumalpass Aug 1, 2026
03ebc57
docs: add task list collapse fix to unreleased
callumalpass Aug 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions PRIVACY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# TaskNotes Privacy Policy

Last updated: June 4, 2026
Last updated: July 11, 2026

## Overview

Expand Down Expand Up @@ -30,9 +30,11 @@ Optional network features:

## OAuth Credentials and Tokens

- OAuth client credentials are configured by you in TaskNotes settings.
- Access and refresh tokens are stored locally on your device.
- You can disconnect providers at any time to revoke TaskNotes access.
- OAuth client IDs and client secrets are configured by you in TaskNotes settings.
- OAuth client credentials, access tokens, and refresh tokens are stored locally in Obsidian Secret Storage, which is encrypted at rest when supported by the operating system.
- These values are not written to TaskNotes' `data.json`.
- Secret Storage is local to the Obsidian installation and vault, so another device may require its own credentials and calendar connection.
- You can disconnect providers at any time to revoke TaskNotes access. Disconnecting retains the OAuth app credentials for reconnection; **Forget saved credentials** removes them from Secret Storage.

## Third-Party Services (When Enabled)

Expand All @@ -50,7 +52,7 @@ Optional network features:
## Data Deletion

You can stop TaskNotes processing by disabling the plugin.
You can remove plugin settings by uninstalling the plugin.
You can remove plugin settings by uninstalling the plugin. Before uninstalling, disconnect calendar providers and use **Forget saved credentials** to remove OAuth values from Obsidian Secret Storage.
Your notes remain in your vault.

## Changes to This Policy
Expand Down
6 changes: 4 additions & 2 deletions docs/calendar-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ Next, add delegated Microsoft Graph API permissions (`Calendars.Read`, `Calendar

## Security Notes

Credentials and tokens are stored locally in your Obsidian data. Tokens refresh automatically, calendar data syncs directly between your vault and provider, and you can disconnect at any time to revoke access.
OAuth client IDs, client secrets, and account tokens are stored locally in Obsidian Secret Storage, which is encrypted at rest when supported by the operating system. They are not written to TaskNotes' `data.json`. Tokens refresh automatically, calendar data syncs directly between your vault and provider, and you can disconnect at any time to revoke account access.

Secret Storage is local to the Obsidian installation and vault. When setting up TaskNotes on another device, enter the OAuth app credentials and connect the calendar again. After disconnecting, use **Forget saved credentials** if you also want to remove the client ID and client secret.

## Troubleshooting

Expand All @@ -59,4 +61,4 @@ Disconnect and reconnect to refresh OAuth tokens, then re-check provider-side ca

**Connection lost after Obsidian restart**

Tokens should persist between sessions. If reconnection is required each restart, investigate vault or plugin-data file permissions.
Tokens should persist between sessions. If reconnection is required each restart, check whether Obsidian Secret Storage is available and retaining secrets for the vault.
3 changes: 1 addition & 2 deletions docs/features/calendar-integration.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Calendar Integration


TaskNotes provides calendar integration through OAuth-connected calendar services, two Bases-powered calendar views, and read-only ICS calendar subscriptions.

## OAuth Calendar Integration
Expand Down Expand Up @@ -31,7 +30,7 @@ OAuth calendar integration requires creating an OAuth application with your cale

### Token Management

TaskNotes stores OAuth access tokens and refresh tokens locally. Tokens are refreshed automatically before expiration. You can revoke access at any time through the integrations settings.
TaskNotes stores OAuth client credentials, access tokens, and refresh tokens in Obsidian Secret Storage, which is encrypted at rest when supported by the operating system and kept separate from TaskNotes' `data.json`. Tokens are refreshed automatically before expiration. You can revoke account access or forget the saved OAuth app credentials through the integrations settings.

## Calendar Views

Expand Down
20 changes: 20 additions & 0 deletions docs/features/recurring-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,26 @@ Occurrence notes can use a separate template from regular new tasks. Set `occurr

The parent task remains the source of the recurrence rule and series history. Occurrence notes do not copy the parent's `recurrence`, `complete_instances`, `skipped_instances`, `completedDate`, calendar provider IDs, or `timeEntries`. New time entries belong to the occurrence note once you track time there.

### Occurrence Filenames

By default, materialized occurrence notes use the existing filename behavior: the parent title followed by a numeric suffix. To opt in to custom filenames, set **Occurrence filename template** under **Settings → Task Properties → Title**. For example, `{{title}} — {{occurrenceDate}}` produces `Weekly review — 2026-08-01.md`.

Occurrence filename templates support all regular filename variables plus these occurrence-specific variables:

- `{{occurrenceDate}}` - occurrence date, such as `2026-08-01`
- `{{occurrenceWeek}}` - ISO week, such as `2026-W31`
- `{{occurrenceMonth}}` - month, such as `2026-08`
- `{{occurrenceYear}}` - year, such as `2026`
- `{{occurrenceMonthName}}` - full month name, such as `August`

Choose the date granularity explicitly in the template; TaskNotes does not infer it from the recurrence rule. A recurring parent can override the global template with the frontmatter property configured by **Occurrence template override property** (by default, `occurrenceFilenameTemplate`):

```yaml
occurrenceFilenameTemplate: "{{title}} ({{occurrenceWeek}})"
```

Leaving the global template empty preserves the existing filename behavior. TaskNotes never renames existing occurrence notes, and filename collisions continue to receive a numeric suffix.

### Occurrence Note Policies

Each recurring parent has an **Occurrence notes** submenu under its recurrence menu:
Expand Down
2 changes: 2 additions & 0 deletions docs/features/template-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Variables for task-specific data.
| `{{projects}}` | All projects joined by `/` | No | Yes | `ProjectA/ProjectB` |
| `{{projectFilePath}}` | Full path of the first project, without `.md` | No | Yes | `Work/Projects/ProjectA` |
| `{{projectFilePaths}}` | Full paths of all projects, joined by `/` | No | Yes | `Work/Alpha/Personal/Beta` |
| `{{projectFolder}}` | Folder containing the first project note (its file path without the note's own name) | No | Yes | `Work/Projects` |
| `{{projectFolders}}` | Folders of all projects, joined by `/` | No | Yes | `Work/Personal` |
| `{{dueDate}}` | Task due date | Yes | Yes | `2025-01-15` |
| `{{scheduledDate}}` | Task scheduled date | Yes | Yes | `2025-01-10` |

Expand Down
12 changes: 7 additions & 5 deletions docs/privacy.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# TaskNotes Privacy Policy

Last updated: June 4, 2026
Last updated: July 11, 2026

## Overview

Expand Down Expand Up @@ -30,9 +30,11 @@ Optional network features:

## OAuth Credentials and Tokens

- OAuth client credentials are configured by you in TaskNotes settings.
- Access and refresh tokens are stored locally on your device.
- You can disconnect providers at any time to revoke TaskNotes access.
- OAuth client IDs and client secrets are configured by you in TaskNotes settings.
- OAuth client credentials, access tokens, and refresh tokens are stored locally in Obsidian Secret Storage, which is encrypted at rest when supported by the operating system.
- These values are not written to TaskNotes' `data.json`.
- Secret Storage is local to the Obsidian installation and vault, so another device may require its own credentials and calendar connection.
- You can disconnect providers at any time to revoke TaskNotes access. Disconnecting retains the OAuth app credentials for reconnection; **Forget saved credentials** removes them from Secret Storage.

## Third-Party Services (When Enabled)

Expand All @@ -50,7 +52,7 @@ Optional network features:
## Data Deletion

You can stop TaskNotes processing by disabling the plugin.
You can remove plugin settings by uninstalling the plugin.
You can remove plugin settings by uninstalling the plugin. Before uninstalling, disconnect calendar providers and use **Forget saved credentials** to remove OAuth values from Obsidian Secret Storage.
Your notes remain in your vault.

## Changes to This Policy
Expand Down
53 changes: 53 additions & 0 deletions docs/releases/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,37 @@ When a change has user-facing documentation, include a canonical tasknotes.dev l

-->

## Security

- Calendar OAuth credentials and account tokens are now stored in Obsidian Secret Storage instead of TaskNotes' `data.json`, with automatic migration for existing connections. See [Calendar Integration](https://tasknotes.dev/features/calendar-integration/).
- Thanks to @mcuste for the contribution

## Added

- (#2126, #2134) Added optional filename templates for materialized recurring
occurrence notes, with explicit date, ISO week, month, year, and month-name
variables plus per-parent overrides. Existing naming remains unchanged until a
template is configured. See [Recurring Tasks](https://tasknotes.dev/features/recurring-tasks/#occurrence-filenames).
Thanks to @raphaelfaouakhiri for reporting and implementing this.
- (#2105) Added `{{projectFolder}}` and `{{projectFolders}}` folder template
variables for storing tasks alongside linked project notes. See
[Template Variables](https://tasknotes.dev/features/template-variables/).
Thanks to @carypruitt for this contribution.

## Fixed

- (#2166) Fixed Task List views configured to start collapsed so the first
chevron click expands only the selected group instead of expanding every
other group. Thanks to @renatomen for reporting and fixing this.
- (#2064, #2066) Recurring tasks now advance correctly after their next
scheduled date is manually adjusted, preserving due-date offsets and times
without jumping back to an earlier occurrence. Thanks to @chmac for reporting
and fixing this.
- (#2081, #2103) Kept task card and relationships widgets visible in reading mode
when Obsidian scroll or preview updates remove their DOM, and refreshed visible
widgets promptly after metadata changes. Thanks to @mukhozhuk for reporting and
debugging this and @martin-forge for fixing it.

## Changed

- Generated TaskNotes type contracts now include configured natural-language
Expand All @@ -44,3 +75,25 @@ When a change has user-facing documentation, include a canonical tasknotes.dev l
guides for adopting TaskNotes in an existing vault, mobile use, custom Bases,
and backup and recovery. See the
[TaskNotes documentation](https://tasknotes.dev/).

## Fixed

- (#2018) Fixed **Hide empty columns** in Kanban views with swimlanes so columns
with no visible tasks are hidden while pinned columns remain. Thanks to
@scottTomaszewski for reporting and fixing this.
- Fixed recurring all-day ICS subscription events keeping the original end date
on later instances, which could cause calendar list views to show events under
the wrong day. Thanks to @abbiefalls90.
- (#2033) Fixed the project folder badge on task cards so, when expandable
subtasks are enabled, it expands or collapses inline subtasks instead of
showing an unavailable-action notice. Thanks to @abbiefalls90.
- (#2040, #2041) Stopped newly created tasks from filling the Google Calendar
retry queue when calendar export is disabled. Thanks to @chmac for reporting
and fixing this.
- (#2046, #2051) The date and time picker now focuses the natural-language input
when it is enabled, making keyboard-driven quick actions ready for immediate
typing. Thanks to @DevOps-Toast for reporting this and @ther12k for fixing it.
- (#2125, #2129) Materialized recurring occurrence notes now record the date
they were actually completed, while the parent recurring task continues to
track the occurrence date. Thanks to @raphaelfaouakhiri for reporting and
fixing this.
9 changes: 5 additions & 4 deletions docs/settings/integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ OAuth integration requires creating your own OAuth application with Google and/o

### Google Calendar

Provide **Client ID** and **Client Secret** from Google Cloud Console, then use **Connect Google Calendar** to complete OAuth loopback authentication. **Disconnect** revokes local credentials.
Provide **Client ID** and **Client Secret** from Google Cloud Console, then use **Connect Google Calendar** to complete OAuth loopback authentication. **Disconnect** revokes account tokens while retaining the OAuth app credentials for reconnection. Use **Forget saved credentials** to remove the client ID and client secret.

The **Target calendar** setting used for exporting tasks to Google Calendar is also used as the default selection when creating a manual external calendar event from the calendar view. If the target calendar is unavailable, TaskNotes falls back to the provider's primary calendar.

Expand All @@ -61,7 +61,7 @@ When connected, displays:

### Microsoft Outlook Calendar

Provide **Client ID** and **Client Secret** from Azure App Registration, then use **Connect Microsoft Calendar** to authenticate. **Disconnect** removes stored credentials and sync access.
Provide **Client ID** and **Client Secret** from Azure App Registration, then use **Connect Microsoft Calendar** to authenticate. **Disconnect** revokes account tokens while retaining the OAuth app credentials for reconnection. Use **Forget saved credentials** to remove the client ID and client secret.

When connected, displays:
- Connected account email
Expand All @@ -70,10 +70,11 @@ When connected, displays:

### Security

- OAuth credentials are stored locally in Obsidian's data folder
- OAuth client credentials and account tokens are stored in Obsidian Secret Storage, which is encrypted at rest when supported by the operating system
- OAuth credentials and account tokens are not written to TaskNotes' `data.json`
- Access tokens refresh automatically
- Calendar data syncs directly between Obsidian and the calendar provider (no intermediary servers)
- Disconnect at any time to revoke access
- Disconnect at any time to revoke account access; use **Forget saved credentials** to remove the OAuth app credentials

## Calendar subscriptions (ICS)

Expand Down
6 changes: 6 additions & 0 deletions docs/settings/task-defaults.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ The **Default Tasks Folder** setting supports dynamic folder creation using temp
- `{{projects}}` - All projects from the task's projects array, joined by `/`
- `{{projectFilePath}}` - Full path of the first project, without `.md`
- `{{projectFilePaths}}` - Full paths of all projects, without `.md`, joined by `/`
- `{{projectFolder}}` - Folder containing the first project note (the project file path without the note's own name); empty when the project note is at the top level. Use this to store tasks beside their project note, e.g. `{{projectFolder}}` stores a task for `[[Areas/EFC/EFC]]` in `Areas/EFC/`
- `{{projectFolders}}` - Folders of all projects, joined by `/`
- `{{priority}}` - Task priority (e.g., "high", "medium", "low")
- `{{status}}` - Task status (e.g., "todo", "in-progress", "done")
- `{{title}}` - Task title (sanitized for folder names)
Expand Down Expand Up @@ -209,6 +211,10 @@ Date/time components provide uniqueness without relying only on title text.
- `{{uuid}}` - UUID v4 (e.g., "550e8400-e29b-41d4-a716-446655440000")
- `{{nano}}` - Nano ID with timestamp and random string

### Materialized Occurrence Filename Variables

Materialized recurring occurrence notes can use a separate, optional filename template. It supports all variables above plus explicit occurrence date, ISO week, month, year, and month-name variables. See [Recurring Tasks](../features/recurring-tasks.md#occurrence-filenames) for configuration, per-parent overrides, and examples.

### Filename Template Examples

**Date-based with title:**
Expand Down
7 changes: 6 additions & 1 deletion i18n.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,10 @@
"settings.taskProperties.titleCard.filenameFormat": "cf0cb55cf575b23cf5f0d5872fad7e82f6c1d028",
"settings.taskProperties.titleCard.customTemplate": "39448a2ba1e6f74f53c856ae2b7c9ee2fd3029c9",
"settings.taskProperties.titleCard.legacySyntaxWarning": "1d18778142343b6959fb00f6acb0dbf4f575b40e",
"settings.taskProperties.titleCard.occurrenceFilenameTemplate": "57abe4824766d21a8afefcce7c29295b80ff8eeb",
"settings.taskProperties.titleCard.occurrenceFilenameTemplateHelp": "09d58a64109a84e279ea82ef2aebefd00b548cb8",
"settings.taskProperties.titleCard.occurrenceFilenameProperty": "1f6abc08c12cb021b16e974bd80bf40590c75e61",
"settings.taskProperties.titleCard.occurrenceFilenamePropertyHelp": "0a3f6bb8068175d9d613b581013699bc157614a4",
"settings.taskProperties.tagsCard.nativeObsidianTags": "c062ef944dbbfbde38a1c80dee244e9f0e38c6bf",
"settings.taskProperties.remindersCard.defaultReminders": "87ff17b932d9c3612442d485ae6dd415e628bdc0",
"settings.taskProperties.taskStatuses.header": "8db340a4c47c03e7bae3e0030f9ef2356b9dd5de",
Expand Down Expand Up @@ -1995,7 +1999,8 @@
"ui.taskCard.reminderTooltipOne": "77575376a67811906b16a84a69f482d3e71c8fc3",
"ui.taskCard.reminderTooltipMany": "b92ef7c3a154324b61a517693ae0e34f79237d9c",
"ui.taskCard.detailsTooltip": "76535db67448f9c312e90031c889cdc58381ae73",
"ui.taskCard.projectTooltip": "0236231ede6436c6aa38eb74d5b4467c9680945a",
"ui.taskCard.projectTooltip": "cd359c35a908c00e4e72047651ece2063270ec4b",
"ui.taskCard.projectIndicatorTooltip": "2b40a2d7b3604874a55787a593ac354c91de54a8",
"ui.taskCard.expandSubtasks": "071739c23c0cef8acf5b704018981d0eaf267f39",
"ui.taskCard.collapseSubtasks": "83f3a3fde26f5b42a42b89bcbde737e2472781a9",
"ui.taskCard.dueToday": "08297268e2e02748afb5a2434c8f1aaec58e1d6b",
Expand Down
Loading