TaskNotes

Contributing

TaskNotes is an open-source Obsidian plugin. Contributions are welcome, whether you are fixing a bug, adding a feature, improving documentation, or reporting an issue.

Getting Started

  1. Fork callumalpass/tasknotes on GitHub
  2. Clone your fork
  3. Install dependencies with bun install (or npm install)
  4. Set up a development vault (see below)
  5. Start the dev server and begin making changes

Development Setup

TaskNotes uses Bun as its package manager and test runner. Node.js with npm also works if you prefer.

bun install        # Install dependencies
bun run dev        # Watch mode -- rebuilds on every change
bun run build      # Production build (type-check + minify)

Task list view showing the development vault with test data

Dev Vault

The recommended setup is to clone the repo directly into a vault's plugin folder:

your-dev-vault/
  .obsidian/
    plugins/
      tasknotes/                <-- clone here
  TaskNotes/
    Tasks/                      <-- generated task files
    Views/                      <-- default .base views
    Demos/                      <-- demo .base files
  User-DB/
    People/                     <-- generated person notes
    Groups/                     <-- generated group notes
  Document Library, Knowledge/  <-- generated document notes

With this layout, bun run dev rebuilds main.js and styles.css in place. Install the Hot Reload community plugin in your dev vault for automatic reloading whenever the build output changes.

Test Data

A test data generator populates the dev vault with realistic content: person notes, group notes, document notes, task notes, and demo .base views. Run it after cloning to get a working dev vault, or any time you need to reset to a clean state (for example, after testing bulk convert and the documents have extra frontmatter fields).

Option A: Test Fixtures Plugin (recommended)

Install the TaskNotes Test Fixtures plugin via BRAT (cybersader/tasknotes-test-fixtures). It provides the same test data through Obsidian commands -- no terminal needed, works on mobile too.

Command Description
Generate all test data Creates all files (overwrites existing)
Clean and regenerate all test data Full reset -- deletes then recreates
Remove all generated test data Deletes without regenerating

Tip: You can also clone the test fixtures repo into .obsidian/plugins/ and modify it directly. This keeps all contributors on the same set of fixtures and lets you create custom commands for specific testing scenarios (e.g. overdue-only tasks, multi-user shared vault setups). Edit src/main.ts, run npm run build, and reload Obsidian.

Option B: Node script

# Generate all test data (overwrites generated files, ignores your own files)
node scripts/generate-test-data.mjs          # or: bun run generate-test-data

# Full reset -- delete all generated data, then regenerate from scratch
node scripts/generate-test-data.mjs --clean  # or: bun run generate-test-data:clean

What --clean removes:

  • User-DB/People/ and User-DB/Groups/ -- all files
  • TaskNotes/Tasks/ -- all files
  • Document Library, Knowledge/ subdirectories (Projects, Compliance, Technical, HR, Meeting Notes, Research, Templates, Design, Operations, Security) -- all files in these folders

What --clean does NOT touch:

  • Your own files at the root of Document Library, Knowledge/ (e.g. personal notes, policies you created)
  • The TaskNotes/Demos/ and TaskNotes/Views/ folders (.base files are managed separately via test-fixtures/)

Resetting demo .base views (if you modified a demo and want to restore it):

The canonical versions live in test-fixtures/TaskNotes/Demos/. Copy them back to the vault:

cp test-fixtures/TaskNotes/Demos/*.base ../../../TaskNotes/Demos/

After running the generator or restoring fixtures, reload Obsidian (Ctrl+P > "Reload app without saving") to pick up the changes.

What You Need

  • Obsidian 1.10.1 or later with the Bases core plugin enabled
  • Bun (or Node.js 18+)
  • A text editor or IDE with TypeScript support

Project Structure

tasknotes/
  src/                  TypeScript source code
    bases/              Bases view system (rendering, toolbar, property mapping)
    bulk/               Bulk tasking engines (generate, convert, edit)
    identity/           Device identity and person/group note discovery
    modals/             Modal dialogs (task creation, edit, bulk, reminders)
    notifications/      Background monitoring, toast, bell badge
    services/           Core business logic (task CRUD, field mapping)
    settings/           Settings UI and defaults
    ui/                 Reusable UI components (PropertyPicker, pickers)
    utils/              Shared utilities
  styles/               CSS source files (concatenated at build time)
  docs/                 Documentation (this site)
  tests/                Jest unit and integration tests
  e2e/                  Playwright end-to-end tests
  main.js               Build output (do not edit directly)
  styles.css            CSS build output (do not edit directly)
  manifest.json         Obsidian plugin manifest
  package.json          Dependencies and scripts

Key files to know:

File Purpose
src/main.ts Plugin entry point, command registration, lifecycle
src/services/TaskService.ts Task creation, update, deletion
src/services/FieldMapper.ts Translates between internal and user-configured property names
src/bases/BasesViewBase.ts Base class for all TaskNotes Bases view types
esbuild.config.mjs Build configuration
build-css.mjs CSS concatenation script

Building and Testing

Build Commands

bun run dev          # Watch mode (CSS + esbuild, rebuilds on change)
bun run build        # Production build (CSS + type-check + esbuild)
bun run build-css    # Rebuild CSS only

Running Tests

bun test             # Run all Jest tests
bun run test:watch   # Watch mode
bun run test:unit    # Unit tests only
bun run test:integration   # Integration tests only

End-to-End Tests

TaskNotes has a Playwright test suite that connects to a running Obsidian instance via Chrome DevTools Protocol. E2E tests use a separate vault (tasknotes-e2e-vault/) to avoid interfering with your dev vault.

bun run e2e:setup    # First-time setup (Linux/WSL)
bun run build:test   # Build and copy to e2e vault
bun run e2e          # Run the full test suite

On Windows and macOS, setup auto-detects the Obsidian installation. On Linux/WSL, the setup script extracts the Obsidian AppImage.

Architecture Overview

TaskNotes is built around a few key systems:

Bases Integration. TaskNotes extends Obsidian's Bases with custom view types (Task List, Kanban, Calendar, Upcoming, Agenda). Each view type extends BasesViewBase, which handles data loading, filtering, and rendering. The BasesToolbarInjector adds TaskNotes buttons to native Bases views.

Task Service. TaskService handles creating, reading, updating, and deleting task files. FieldMapper translates between internal field names (like due) and user-configured property names (like deadline). Per-task overrides are resolved via fieldOverrideUtils.

Notification System. BasesQueryWatcher monitors .base files with notify: true, evaluates their queries in the background, and triggers the toast notification and bell badge when items match. VaultWideNotificationService aggregates notifications from views and upstream reminders.

Bulk Tasking. BulkOperationEngine routes to specialized engines: BulkTaskEngine (generate), BulkConvertEngine (convert in-place), BulkEditEngine (modify properties), and BulkUpdateEngine (reschedule, archive, complete, delete).

Identity System. DeviceIdentityManager assigns each device a UUID. UserRegistry maps devices to person notes. PersonNoteService discovers person notes and GroupRegistry discovers groups with recursive member resolution.

Pull Request Process

  1. Branch from main. Create a feature branch with a descriptive name.
  2. Make focused changes. Keep PRs small and focused on one thing. A bug fix and a new feature should be separate PRs.
  3. Write tests where possible. Unit tests for logic, E2E tests for UI behavior.
  4. Follow existing patterns. Look at similar code in the codebase before introducing new patterns.
  5. Describe your changes. The PR body should explain what changed and why. Include screenshots for UI changes.
  6. Update documentation. If your change adds or modifies user-facing behavior, update the relevant docs page.

Coding Standards

  • TypeScript. All source code is TypeScript. Avoid any types where a more specific type is reasonable.
  • Use existing utilities. Check src/utils/ and src/services/ before creating new helpers. Many common operations already have functions.
  • Follow Obsidian guidelines. The Obsidian Plugin Guidelines apply. Key points: sentence case for UI text, no manual HTML headings in settings tabs, use Setting API for settings UI.
  • ESLint. The project uses eslint-plugin-obsidianmd for Obsidian-specific linting rules. Run bun run lint before submitting.
  • CSS. Styles live in styles/ as individual files. Use tn- prefixed class names to avoid conflicts with Obsidian's styles. The build concatenates all CSS files into styles.css.

Documentation

Documentation lives in docs/ and is built with a custom static site builder in docs-builder/. The builder reads markdown from docs/, processes it with marked, and outputs HTML to docs-builder/dist/. Navigation is read from mkdocs.yml (the nav: section only -- MkDocs itself is not used for the production site).

Previewing the docs locally

First-time setup:

cd docs-builder
npm install          # or: bun install

Build and serve:

cd docs-builder
npm run dev          # or: bun run dev -- builds to dist/ and serves at http://127.0.0.1:4321

Or run the steps separately:

cd docs-builder
node build.js                                    # build only
python3 -m http.server 4321 --directory dist     # serve

Open http://127.0.0.1:4321 in your browser to preview. The builder does not live-reload -- re-run node build.js after edits and refresh the browser.

Writing docs

Images and GIFs go in docs/assets/. Use descriptive filenames like feature-toast-notification.png or bulk-tasking-generate-mode.gif.

Image paths depend on the page's location:

Page location Image path
docs/features/*.md ../assets/filename.png
docs/views/*.md ../assets/filename.png
docs/settings/*.md ../assets/filename.png
docs/*.md (top-level) assets/filename.png

Capturing screenshots in Obsidian: Use the Custom Attachment Location community plugin to route pasted images directly to docs/assets/. Set the attachment folder to the docs assets path so screenshots land in the right place without manual copying.

Using test fixtures for docs: The TaskNotes Test Fixtures plugin is essential for docs work. Use it to:

  • Generate demo data before capturing screenshots or GIFs — gives you realistic tasks, persons, groups, documents, and demo .base views
  • Reset between takes — run "Clean and regenerate" to get a fresh state after modifying tasks during recording
  • Test features rapidly — the generated data covers most features (recurring tasks, dependencies, reminders, bulk operations, shared vault scenarios)
  • Reproduce examples — each docs page has a recording script (in an HTML comment at the top) that references specific demo .base files from the fixtures

Install via BRAT (cybersader/tasknotes-test-fixtures) or clone into .obsidian/plugins/. See Test Data above for full details.

Placeholders: When adding a feature before screenshots are ready, use HTML comment placeholders:

<!-- SCREENSHOT: Description of what the screenshot should show -->
<!-- GIF: Description of the interaction to capture -->
<!-- VIDEO: Description of the workflow to record -->

Replace placeholders with actual images as they become available.

Writing style: Natural descriptions, concrete examples, no jargon. Use double dashes (--) instead of em dashes. Link to Obsidian help docs where relevant. Follow the breadcrumb pattern at the top of each page ([← Back to Features](../features.md)).

Navigation: Update mkdocs.yml when adding new pages. Place feature pages under the Features nav section, view pages under Views.

Reporting Issues and Feature Requests

If you find a bug or have a feature request, open an issue on GitHub. Include:

  • Steps to reproduce the issue
  • What you expected to happen
  • What actually happened
  • Your Obsidian version and TaskNotes version
  • Debug log output if applicable (see Collecting Debug Logs)

For troubleshooting common problems before filing an issue, see Troubleshooting.

Resources