Changelog

All notable changes to Obsidian Project Planner will be documented on this page. The format is based on Keep a Changelog.

Versions


Changelog

All notable changes to Obsidian Project Planner will be documented in this file.

 

[0.8.2] - 2026-04-17

Fixed

Code Audit — Obsidian Community Plugin Guidelines & Best Practices

  • alert() replaced with Notice (TaskDetailView): Removed browser alert() call in favor of Obsidian's Notice API, as required by community plugin guidelines
  • Canvas event listeners migrated (DependencyGraphView): Replaced manual canvas.addEventListener("mousedown"/"dblclick") with this.registerDomEvent() for automatic cleanup on view close
  • any type annotations removed (GridView, TaskSync): Eliminated 4× any casts in GridView (statusOptions.map, priorityOptions.map, buckets.find, reorderableColumns.filter) and replaced yaml: any with Record<string, unknown> in TaskSync
  • Path traversal sanitization (Settings): projectsBasePath now strips .. segments and leading / to prevent directory traversal

Resource & Lifecycle Cleanup

  • DashboardView keydown listener leak: Modal keydown handlers (showTaskListModal, showCostReportModal) are now tracked and removed in dismissModal(), preventing orphaned listeners
  • DependencyGraphView post-close guard: Added closed flag to prevent refresh() and startSimulation() animation loop from executing after view close
  • DailyNoteTaskScanner timeout cleanup: Added destroy() method that clears pending scanTimeout; called from main.ts onunload() to prevent post-unload scan callbacks
  • GanttView render guard: Added isRendering/renderPending guard (matching BoardView pattern) to prevent overlapping renders from corrupting scroll state

Performance

  • BoardView dragover optimization: Replaced document.querySelectorAll() on every dragover event with tracked lastHighlightedCard reference — O(1) class toggle instead of full DOM scan

Type Safety

  • webkitUserSelect any casts removed: Replaced 9× (document.body.style as any).webkitUserSelect across TaskDetailView, GanttView, and GridView with style.setProperty("-webkit-user-select", ...) / style.removeProperty("-webkit-user-select")

Input Validation

  • Clipboard API error handling (TaskDetailView): navigator.clipboard.writeText() now wrapped in try/catch with Notice fallback for denied permissions
  • Numeric settings validation (Settings): Budget and hourly rate inputs now validate Number.isFinite() and >= 0, rejecting NaN and negative values

 

[0.8.1] - 2026-03-15

Fixed

Obsidian Community Plugin Guidelines

  • .gitignore updated: Removed main.js and main.js.map from ignore list so build outputs are tracked in version control (required by Obsidian plugin registry)
  • isDesktopOnly set to true: Plugin uses Node crypto and desktop-only APIs — now correctly declared in manifest.json
  • Cross-platform clean script: Replaced PowerShell-only Remove-Item in package.json with portable rm -rf

Event Listener & Resource Cleanup

  • DependencyGraphView listener leaks: Replaced manual window.addEventListener("resize") and document.addEventListener("mousemove/mouseup") with Obsidian's registerDomEvent() for automatic cleanup on view close
  • Unsafe TaskDetailView cast: Replaced as TaskDetailView cast with duck-type check ('setTask' in view) to safely handle cases where the view hasn't initialized

Data Integrity

  • Hash collision in daily note task IDs: Replaced 32-bit hash-based generateStableTaskId() with crypto.randomUUID(), eliminating collision risk for imported daily note tasks
  • Invalid date handling: Added isValidDateStr() validation in TaskStore and parseLocalDate() in GanttView — invalid or malformed date strings no longer produce NaN dates or silent rendering errors
  • createFolder crash: Wrapped vault.createFolder() calls in main.ts and TaskSync.ts with try-catch to prevent crashes when the folder already exists

Performance

  • O(1) task lookups: Added taskIndex Map to TaskStore — getTaskById() now uses Map lookup instead of Array.find(), improving performance for large task lists
  • taskIndex not updated in addTaskToProject: Fixed a regression where tasks added via DailyNoteTaskScanner were missing from the index, causing getTaskById() to return undefined
  • Incremental grid rendering: GridView now renders rows in batches of 100 with scroll-triggered loading, reducing initial render time for projects with hundreds of tasks

Changed

  • View activation deduplicated: Six near-identical view activation methods (activateView, activateBoardView, activateDashboardView, activateGanttView, activateMyDayView, openDependencyGraph) consolidated into a shared openViewByType() helper
  • Dead code removed: Deleted unused uuid.ts utility and its test file

[0.8.0] - 2026-03-08

Added

My Tasks View (Today)

  • New "My Tasks" view accessible from the header navigation (sun icon) and the command palette ("Open My Tasks")
  • Cross-project task aggregation: Shows all tasks due today across every project in a single grid table
  • Summary bar with task count and progress indicator (X/Y done) with animated fill
  • Filters: Priority dropdown, text search, and "Show completed" toggle
  • Sortable rows: Incomplete tasks first, then sorted by priority weight (Critical → Low)
  • Inline actions: Checkbox to toggle completion, clickable title to open Task Detail, right-click context menu
  • Status & priority pills reusing existing design system styles
  • Empty states: Distinct messages for "no tasks due today" vs. "all tasks filtered out"
  • Scroll preservation with renderVersion guard to prevent stale restore on rapid re-renders

My Tasks View (Week)

  • Outlook-style weekly layout: 7 day columns (Monday–Sunday) displayed in a CSS grid
  • Today/Week segmented toggle in the view header to switch between modes; filters are shared across both
  • Today highlight: Current day column gets an accent border and the date number displays in an accent-colored circle badge
  • Compact task cards: Each card shows a checkbox, clickable title, project name, and priority pill
  • Week navigation: Previous/next chevron buttons and a "This Week" quick-return button in the toolbar
  • Date range label above the columns (e.g., "March 2 – 8, 2026"), adapts when the week spans two months
  • Per-column task counts and "Filtered" indicator when all tasks in a day are hidden by filters

Cost Tracking System

  • Per-task cost fields: costEstimate, costActual, costType ("fixed" or "hourly"), and optional hourlyRate override
  • Two cost modes:
  • Fixed: User enters estimated and actual cost directly
  • Hourly: Cost auto-calculated from effort hours × hourly rate (read-only display)
  • TaskDetailView — Cost section: Cost Type dropdown, Estimated/Actual/Variance display, hourly rate override input with project default hint
  • GridView — Two new columns: "Est. Cost" and "Actual Cost", toggleable from the Columns menu, formatted with project currency symbol
  • Parent task cost roll-up: Parent tasks automatically aggregate estimated and actual costs from children (same pattern as effort roll-up)
  • Project-level budget settings: Total Budget, Default Hourly Rate, and Currency Symbol fields in plugin settings (per-project)
  • DashboardView — Budget & Cost card: Budget progress bar (green → yellow at 75% → red at 90%), KPI cards for Budget, Estimated, Actual, Remaining, and Over-Budget task count
  • Cost Report modal: Tabbed breakdown (By Bucket, By Status, By Priority, Over Budget) with totals row and variance coloring; accessible via "View Cost Report" button on Dashboard
  • costUtils.ts: New utility module with all cost calculation logic — per-task estimated/actual, roll-ups, project summary, breakdown grouping, and currency formatting
  • Fully backward-compatible: All cost fields are optional; existing data loads without migration

Fixed

Critical & High Severity

  • Settings save race condition: saveSettings() now uses getCachedRawData() to read task data synchronously, preventing concurrent read/write from blanking task buckets
  • Task note creation path: createTaskNotes() now respects projectsBasePath setting instead of always writing to vault root
  • TaskSync delete handler: Rebuilt to use a pre-computed taskIdByPath map, fixing O(n²) lookup and stale-closure bugs when task markdown files are deleted
  • Window listener leaks: GridView and TaskDetailView now clean up mousemove/mouseup listeners if the view is closed mid-drag (column resize or subtask reorder)

Scroll Position Reset

  • Stale rAF restore: Added renderVersion counter to GridView and BoardView; scroll-restore requestAnimationFrame callbacks are discarded if a newer render has occurred
  • Double-save on inline edits: createEditableSelectCell and createEditableDateOnlyCell no longer fire both onchange and onblur saves — a let saved = false guard ensures only one write per edit
  • Horizontal scroll lost: scrollLeft is now saved and restored alongside scrollTop in GridView
  • saveScrollPosition() idempotency: The method now only captures scroll coordinates when no save is already pending

Task Creation UX

  • New task animation glitch: Removed the slideInRow CSS animation and planner-row-new class that caused rows to disappear then pop in; focus now uses requestAnimationFrame instead of a 150ms setTimeout
  • "Add Task Above" wrong position: Rewrote to use new addTaskAtIndex() on TaskStore — a single atomic insert at the correct index with one event emit, replacing the old 3-mutation sequence (addTask + updateTask + setOrder)

Bug Audit (23 fixes)

  • GanttView UTC date shift: toISODate() now uses local date components instead of toISOString().slice(), preventing off-by-one day errors near midnight
  • Cross-project task updates: taskStore.updateTask() now searches across all projects via tasksByProject when the task isn't found in the active project — fixes My Tasks view edits silently failing
  • GridView parent drag dropping wrong tasks: Parent drag now uses recursive getAllDescendants() helper to collect all nested children, not just direct children
  • BoardView checkbox desyncs status: Checkbox toggle now passes both completed and status to updateTask(), keeping them in sync
  • TaskDetailView effort remaining not saved: commitCompleted handler now saves both effortCompleted and effortRemaining in a single update
  • GanttView checkbox desyncs status: Same fix as BoardView — checkbox passes both completed and status
  • GridView showCompleted filter ignored in renderTableBody: Added showCompleted filtering inside renderTableBody() so completed tasks are properly hidden
  • GridView auto-scroll wrong selector: Fixed CSS selector from .planner-grid-wrapper to .planner-grid-content for scroll-into-view on new task creation
  • GanttView resizer listener leak: Added activeResizerCleanup tracking so each new resize cleanly removes the previous listener pair
  • DashboardView modal DOM leak + missing Escape handler: Added activeModal/activeOverlay tracking, dismissModal() cleanup method, Escape key dismissal, and cleanup in onClose()
  • DependencyGraphView double-click opens nothing: Double-click now calls plugin.openTaskDetail() instead of the non-existent local method
  • DependencyGraphView stale canvas after drag: Added needsRefresh flag that defers refresh during active drag and triggers redraw on drag end
  • TaskDetailView subtask drag corrupts array: handleSubtaskDrop now clones the subtask array before splice to avoid mutating the shared reference
  • TaskDetailView duration local date parsing: renderDurationRow now parses YYYY-MM-DD as local midnight instead of UTC, preventing off-by-one day display
  • uuid.ts fallback not unique: Fallback now generates ${Date.now()}-${Math.random().toString(36).slice(2, 11)} instead of a simple counter
  • DashboardView renderVersion counter: Added scroll-preservation guard matching GridView's pattern
  • GridView duration shows "0 days": Duration calculation now uses Math.max(1, diffDays) for inclusive day count — same-day start/due shows "1 day"
  • GridView dead updateSortIndicators code: Removed unreferenced method that referenced non-existent DOM
  • BoardView bucket drag off-by-one: Adjusted targetIndex when dragging left-to-right to account for the removed source element
  • GanttView scroll sync thrash: Replaced direct scroll assignment with requestAnimationFrame to prevent layout thrashing during synchronized scrolling
  • DependencyGraphView blurry on HiDPI: Canvas now scales by devicePixelRatio for crisp rendering on Retina/HiDPI displays
  • DailyNoteTaskScanner batched saves: Removed per-line saveTaskLocationMap() calls in parseTaskLine and duplicate branch; single save at end of scanFile
  • DailyNoteTaskScanner file rename colon split: File rename handler now uses lastIndexOf(':') instead of split(':')[1] to safely extract line numbers from paths containing colons

Changed

  • TaskStore gained getCachedRawData() public accessor and addTaskAtIndex(title, index, overrides?) method
  • TaskStore.rollUpParentFields() now aggregates cost data (estimated + actual) from children
  • GridView column menu now uses setChecked() for native checkmark indicators
  • PlannerTask interface extended with costEstimate, costActual, costType, hourlyRate
  • PlannerProject interface extended with budgetTotal, defaultHourlyRate, currencySymbol

[0.7.1] - 2026-02-28

 Fixed

Board View Settings Persistence
- Stale Settings Cache: Fixed a bug where Board view changes (e.g., newly created buckets) were lost between sessions
 - The saveTasks() method wrote tasks using a cached copy of data.json that could hold outdated settings, silently overwriting newer bucket definitions on the next save
 - Fix ensures raw.settings is always synced from the authoritative in-memory settings object before writing to disk

 

[0.7.0] — 2026-02-22

Added

Task Effort Tracking

  • Microsoft Planner-Style Effort System: Full effort tracking with Completed, Remaining, and Total hours
    • Effort Completed: Hours of work done on a task (editable in Grid View and Task Detail)
    • Effort Remaining: Hours of work left (auto-adjusts when completed changes)
    • Effort Total: Read-only sum of Completed + Remaining
    • Duration: Auto-calculated days between Start Date and Due Date
    • % Complete: Auto-derived from effort values using round(completed / total × 100)

Smart Effort Auto-Sync (Microsoft Planner Behavior)

  • Auto-Deduct Remaining: Entering completed hours automatically reduces remaining from the established total
    • Example: 10h total, enter 4h completed → remaining auto-adjusts to 6h
  • Status ↔ Effort Sync: Marking a task "Completed" moves all remaining hours into completed; % Complete at 100% auto-sets status to "Completed"; dropping below 100% from Completed resets to "In Progress"
  • Bidirectional View Sync: Effort changes in Grid View instantly reflect in Task Detail View and vice versa

Effort in All Views

  • Grid View: 5 new columns — % Complete, Effort Done, Effort Left, Effort Total, Duration
    • Effort Done and Effort Left are inline-editable number inputs
    • % Complete, Effort Total, and Duration are read-only calculated cells
    • All new columns support drag-and-drop reordering and show/hide toggles
  • Task Detail View: New Effort section with Duration row, % Complete display (with "calculated from effort" hint), and Completed/Remaining/Total grid
  • Dashboard View: Effort Summary section with progress bar and KPI cards (Total Effort, Completed, Remaining, Avg % Complete) — appears only when tasks have effort data

Markdown Sync for Effort Fields

  • Bidirectional Sync: effortCompleted, effortRemaining, and percentComplete now sync to/from YAML frontmatter in task markdown files
    • Written to frontmatter when values are > 0
    • Parsed back with safe Number() coercion on markdown → JSON sync
    • Duration not synced (derived from startDate/dueDate which are already synced)

Dependency-Driven Auto-Scheduling (MS Project / GanttProject Style)

  • Automatic Date Cascading: When a predecessor task's dates change, all dependent tasks automatically shift their dates
    • Finish-to-Start (FS): Dependent starts the day after predecessor finishes
    • Start-to-Start (SS): Dependent starts when predecessor starts
    • Finish-to-Finish (FF): Dependent finishes when predecessor finishes
    • Start-to-Finish (SF): Dependent finishes when predecessor starts
    • Duration Preservation: Task duration (days between start and due) is maintained when shifting
    • Forward-Only Scheduling: Tasks are only pushed later, never pulled earlier — prevents unexpected schedule compression
    • Recursive Cascade: Changes propagate through the entire dependency chain (A → B → C all shift)
    • Circular Dependency Guard: Visited-set prevents infinite loops in circular dependency graphs
    • Markdown Sync: Cascaded date changes automatically sync to markdown files
  • New Setting: "Auto-schedule dependent tasks" toggle under Dependency Scheduling section (enabled by default)
  • Grid View Indicator: Dependency cells show 📐 icon with "(auto-scheduled)" tooltip when scheduling is active; falls back to 🔗 when disabled

Timeline/Gantt Dependency Arrows (MS Project Style)

  • Visual Dependency Connectors: SVG overlay draws right-angle connector arrows between linked task bars
    • Finish-to-Start (FS): Arrow from predecessor's right edge to successor's left edge
    • Start-to-Start (SS): Arrow from predecessor's left edge to successor's left edge
    • Finish-to-Finish (FF): Arrow from predecessor's right edge to successor's right edge
    • Start-to-Finish (SF): Arrow from predecessor's left edge to successor's right edge
    • Smart Routing: L-shaped orthogonal paths (horizontal → vertical → horizontal) with automatic detour routing when bars overlap horizontally
    • Accent-Colored Lines: Arrows use theme accent color with arrowhead markers for clear directionality
  • Toggle Button: Toolbar button to show/hide dependency arrows (enabled by default)
    • Active state uses accent color styling; toggles with single click
    • Arrows re-render on every view update to stay in sync with task changes

Parent Task Roll-Up (MS Project Style)

  • Automatic Parent Field Calculation: Parent tasks automatically derive their values from subtasks, matching MS Project behavior
    • Date Roll-Up: Parent Start Date = earliest child start; parent Due Date = latest child due
    • Effort Roll-Up: Parent Effort Completed = sum of children; parent Effort Remaining = sum of children
    • % Complete Roll-Up: Duration-weighted average — Σ(childDuration × child%) / Σ(childDuration) — tasks without dates use equal weight (1 day)
    • Status Sync: 100% complete auto-sets parent to "Completed"; dropping below 100% from Completed resets to "In Progress"
    • Upward Cascade: Changes propagate up the hierarchy — grandparent updates when child changes
    • Trigger Points: Roll-up fires on task update, task delete, make-subtask, and promote-subtask operations
    • Markdown Sync: Rolled-up parent values automatically sync to markdown files
  • Read-Only Parent Fields: Rolled-up fields are non-editable in both Grid View and Task Detail View
    • Grid: Cells show italic text with Σ indicator and "Rolled up from subtasks" tooltip
    • Task Detail: Effort inputs replaced with read-only display; date fields shown as static text
    • % Complete hint changes from "(calculated from effort)" to "(rolled up from subtasks)"
  • New Setting: "Auto-calculate parent task fields from subtasks" toggle under Parent Task Roll-Up section (enabled by default)

Fixed

Grid View Column Drag-and-Drop

  • Column Order Sync: New columns added after initial setup are now properly included in the drag-and-drop order array
    • Previously, columns not in the saved gridViewColumnOrder caused indexOf() to return -1, silently breaking drag-and-drop for those columns
    • Fix applied in both loadGridViewSettings() (appends missing columns on load) and ondrop handler (syncs missing columns before reorder)

Grid View Cell Rendering Architecture

  • Dynamic Column Rendering: Refactored renderTaskRow from hardcoded if-blocks to a cellRenderers map iterated in getColumnDefinitions() order
    • Headers and cells now guaranteed to render in the same order regardless of column reordering
    • Row drag logic extracted to dedicated handleRowDragStart() method
    • Eliminates header/cell mismatch bugs when columns are reordered

Grid View Inline Edit Sync

  • Timing Fix: isEditingInline flag now set to false BEFORE updateTask() call instead of after
    • Previously, the subscriber re-render was skipped during the update because the flag hadn't been cleared yet
    • Ensures Grid View reflects changes immediately when editing effort or other fields inline

Scroll Position Preservation Across All Views

  • Board View: Horizontal board scroll and per-column vertical scroll positions are now preserved across re-renders
    • Saves .planner-board-container horizontal scroll and each bucket column's vertical scroll
  • Task Detail View: Scroll position of the detail panel is preserved when task data updates (e.g., status change, effort edit)
  • Dashboard View: Scroll position of the dashboard wrapper is preserved on data-driven re-renders
  • Gantt/Timeline View: All 3 scroll axes preserved — left column vertical, right timeline vertical, and right timeline horizontal
    • Cross-sync suppressed during restore to prevent scroll listener interference
  • Previously, any TaskStore change caused a full container.empty() + rebuild, losing the user's scroll position in all views except Grid View

 

[0.6.13] — 2026-02-10

Added

Grid View Column Reordering

  • Drag-and-Drop Column Headers: Reorder columns in Grid View with Microsoft Planner-style interactions
  • Reorderable Columns: All hideable columns (Title, Status, Priority, Bucket, Tags, Dependencies, Dates) can be reordered
  • Locked Columns: Drag handle, Row number, and Checkbox remain fixed in position
  • Visual Feedback: Dragged column fades to 40% opacity, drop target shows accent outline
  • Cursor States: Grab cursor on hover, grabbing cursor during drag
  • Order Persistence: Column arrangement saved to gridViewColumnOrder setting and preserved across sessions
  • Smart Ordering: Automatically handles new columns not in saved order by appending them
  • Consistent behavior with Board View bucket reordering for intuitive UX

Header View Switcher Icons

  • Icon-Based Navigation: View switcher buttons now use Obsidian icons instead of text labels
  • Dashboard: layout-dashboard icon
  • Grid: table icon
  • Board: layout-list icon
  • Timeline: calendar-range icon
  • Graph: git-fork icon
  • Tooltips show view names on hover for clarity
  • Cleaner, more compact header design matching Obsidian's interface patterns

Fixed

DailyNoteTaskScanner Deduplication System

  • Critical Fix: Task Duplication Prevention — Comprehensive overhaul to prevent duplicate tasks with Obsidian Sync
  • Persisted Location Tracking: Task location map now saved to plugin settings (dailyNoteTaskLocations). Survives plugin reloads and syncs across devices. Previously: in-memory only, lost on every restart → duplicates on reload
  • Content-Based Stable IDs: Replaced random UUIDs with deterministic content hashing. Hash formula: file path + normalized task content. Same task content = same ID across all devices. Prevents sync conflict duplicates between devices
  • Duplicate Detection: Added findDuplicateTaskByContent() to catch existing tasks before import. Checks title match + daily-task-* ID pattern. Updates existing task instead of creating duplicate
  • File Operation Tracking: File rename watcher updates location map keys automatically. File deletion watcher cleans up orphaned location entries. Tasks preserve IDs when daily notes are reorganized
  • Enhanced Metadata: Task descriptions now include source line number. Format: Imported from: [[filename]]\nLine: 42

Documentation

  • DAILY_NOTE_SCANNER_AUDIT.md: Comprehensive security audit documenting all duplication issues and fixes
  • Identified 5 critical/medium severity duplication vectors
  • Documented cross-device sync protection mechanisms
  • Testing checklist for Obsidian Sync scenarios
  • Impact analysis: ~100% duplication rate → near zero with fixes

[0.6.12] — 2026-02-04

Added

Comprehensive Test Suite

  • 313 Automated Tests (98.4% passing): Complete test coverage for all core functionality
  • Unit Tests (214): TaskStore, TaskSync, UUID, DailyNoteTaskScanner, Main Plugin, ProjectPlannerSettingTab
  • Integration Tests (13): End-to-end task workflows across components
  • Utility Tests (99): Date formatting, settings utilities, helper functions
  • Compliance Tests (32): Obsidian plugin manifest and lifecycle validation

Test Organization

  • TaskStore Tests (37): Core operations, hierarchy, multi-project support, state management, legacy migration
  • TaskSync Tests (41): Bidirectional markdown sync, file operations, error handling, sync lock prevention
  • DailyNoteTaskScanner Tests (61): Tag extraction, task parsing, priority/due date detection, file scanning
  • ProjectPlannerSettingTab Tests (37): Settings UI validation, project management, sync configuration
  • Main Plugin Tests (30): Plugin lifecycle, view management, URI protocol, settings persistence
  • UUID Tests (8): Generation, validation, uniqueness (100% coverage)
  • Compliance Tests (32): Manifest validation, lifecycle methods, data safety, performance benchmarks

Test Infrastructure

  • Jest Framework: TypeScript support with ts-jest, JSDOM environment for browser API simulation
  • Obsidian API Mocks: Complete mock suite in tests/__mocks__/obsidian.ts
  • Custom DOM Helpers: Extended HTMLElement methods (createDiv, createEl, empty) for UI testing
  • Test Documentation: Comprehensive TESTING.md guide with examples and best practices
  • ESLint Rules: .eslintrc.obsidian.json with Obsidian-specific patterns and security rules

Fixed

DailyNoteTaskScanner Project Name Parsing

  • Multi-Word Projects: Fixed regex to properly handle project names with hyphens
  • Before: ([^#\\n\\r]+?)(?=\\s|$|#) — stopped at first space
  • After: ([^\\s#]+) — correctly captures hyphenated names
  • Convention: Multi-word projects use hyphens in tags (e.g., #planner/Work-Project)
  • Added 13 edge case tests for project name extraction

Improved

Code Quality & Reliability

  • Bug Prevention: Automated tests catch regressions before they reach users
  • Documentation: Tests serve as executable examples of how code should behave
  • Contributor Confidence: Easy onboarding with comprehensive test suite
  • CI/CD Ready: GitHub Actions can run npm test for automated validation

Compliance Validation

  • Manifest Checks: Validates all required fields, version format, ID conventions
  • Lifecycle Checks: Ensures proper onload/onunload, resource cleanup, error handling
  • Performance Checks: Validates plugin loads within 1 second
  • Data Safety: Tests prevent settings data loss, validate error recovery

[0.6.11] — 2026-02-02

Added

Board View Card Reordering

  • Drag-and-Drop Within Buckets: Enabled precise card reordering within the same bucket
  • Visual Drop Indicators: Blue line appears above or below cards showing exact drop position
  • Smart Position Detection: Automatically detects top half (before) or bottom half (after) based on cursor
  • Task Order Persistence: Reordered cards maintain their position through TaskStore order updates
  • Cross-Bucket Support: Seamlessly handles both reordering within bucket and moving between buckets
  • Smooth Animations: Drop indicator has subtle glow effect for clear visual feedback
  • Preserves all existing drag-to-bucket-column functionality

Improved

Task Details Panel Layout

  • Reorganized Field Order: Improved task details layout for better workflow
  • Description Promoted: Moved Description to appear directly after Task Title (before Status)
  • Checklist Repositioned: Moved Checklist between Tags and Card Preview for easier access
  • New order: Title → Description → Status → Priority → Tags → Checklist → Card Preview → Bucket → Dates → Dependencies → Links
  • More logical grouping of related fields for faster task management

[0.6.10] — 2026-02-01

Fixed

Date Display Timezone Issue

  • Board View: Fixed due dates displaying as one day earlier than set
  • Corrected date parsing to avoid UTC timezone conversion issues
  • Dates now parse correctly by splitting "YYYY-MM-DD" string and creating Date with explicit values
  • Ensures dates display consistently across all timezones
  • Gantt/Timeline View: Fixed start and due dates displaying incorrectly due to timezone conversion
  • Timeline bars now position correctly based on actual date values

Improved

Grid View Inline Edit Polish

  • MS Planner-Level Smoothness: Refined task title editing with optimistic updates and seamless transitions
  • No Disappearing Tasks: Implemented optimistic UI updates — title changes appear instantly without flicker
  • Smooth Fade Transitions: Input field fades out (150ms) as updated text fades in simultaneously
  • Instant Feedback: New value displays immediately before background save completes
  • Scroll Preservation: Viewport position maintained during title edits
  • Escape key smooth fade back to original value; Enter key clean save
  • Background sync happens after UI transition for perceived instant response

Grid View Add New Task Polish

  • Smooth Row Appearance: New tasks slide in and fade in with cubic-bezier easing (300ms animation)
  • Coordinated Focus Timing: Editor activation precisely timed to coordinate with row animation (150ms delay)
  • Inline Editor Fade-In: Input field smoothly fades in when activated (150ms opacity transition)
  • Auto-Selection: Task title automatically selected for immediate editing
  • From task creation → row animation → editor activation → text selection happens in one fluid motion

Grid View Drag-and-Drop Polish

  • Smooth Animations: Ghost element fades in on drag start and fades out on drop (100ms transitions)
  • Drop Indicator Transitions: Line indicator smoothly animates position and opacity changes
  • Performance Optimization: Throttled drop zone calculations to 60fps while keeping ghost movement instant
  • Auto-Scroll: Viewport automatically scrolls when dragging near top/bottom edges (80px threshold)
  • All transitions use consistent easing curves for unified feel

Fixed

Grid View Date Formatting

  • Start Date Neutral Styling: Removed conditional formatting from Start Date column
  • Conditional formatting (red for overdue, blue for today) only applies to Due Date column

Grid View Column Resizing

  • Expandable Table: Fixed column resizing constraints on smaller viewports
  • Changed table from fixed width: 100% to min-width: 100% with width: max-content
  • Horizontal scrolling activates automatically when table exceeds viewport

[0.6.9] — 2026-01-31

Fixed

Grid View Scroll Preservation

  • Smooth Interactions: Fixed page jumping to top after drag-and-drop operations
  • Scroll position is now automatically preserved during all TaskStore operations
  • Eliminated jitter when checking/unchecking tasks
  • Implemented automatic scroll restoration after subscription-based re-renders

Grid View Task Creation

  • New Task Visibility: Fixed newly created tasks sometimes disappearing or flickering when pressing Enter
  • Eliminated all redundant render() calls after TaskStore operations (30+ instances removed)
  • TaskStore's subscription pattern now exclusively handles re-rendering
  • Prevented race conditions between manual renders and subscription-based renders

Markdown Sync Improvements

  • Task Rename Handling: Fixed duplicate markdown notes being created when renaming tasks
  • Old task file is now properly deleted when task title changes
  • Bidirectional Title Sync: Fixed task title changes in markdown files not syncing back to plugin
  • Markdown file is automatically renamed to match new title

Grid View Enhancements

  • Show Completed Tasks Toggle: Fixed toggle in settings not actually filtering tasks
  • Horizontal Scrolling: Enabled horizontal scrolling for Grid View
  • Subtask Drag-and-Drop: Fixed subtasks being pushed out of parent when reordering

[0.6.7] — 2026-01-28

Added

Board View Enhancements

  • Bucket Menu Button: Hover over any bucket header to reveal a "..." menu button for quick bucket actions (rename, change color, add bucket, delete)
  • Inline Bucket Editing: Double-click bucket names to edit them inline. Press Enter to save, Escape to cancel
  • Works for both regular buckets and the Unassigned bucket

Enhanced Context Menu Functionality

  • Cut, Copy, Paste Operations: Task context menu now supports clipboard operations
  • Copy Link to Task: Generate obsidian:// URI deep links to tasks. Automatically copies to clipboard
  • Open Markdown Task Note: Quick access to task markdown files. Auto-creates note if it doesn't exist
  • Available in Grid View and Timeline/Gantt View

Ribbon Icon Customization

  • Configurable Ribbon Icons: Users can now choose which ribbon icons to display in settings
  • Toggle visibility for Grid, Dashboard, Board, Dependency Graph, and Daily Note scan icons
  • Reduces sidebar clutter by hiding unused view shortcuts

Fixed

Code Quality & Plugin Compliance

  • Memory Leak Prevention: Fixed memory leak in Dependency Graph View with proper cleanup of event listeners and animation frames
  • Type Safety Improvements: Removed all (plugin as any) unsafe assertions
  • Data Persistence: Gantt view column width now uses plugin settings instead of localStorage
  • Error Handling: Added proper error handling for vault operations
  • External Links: Updated changelog link to GitHub releases page

Timeline View Improvements

  • Synchronized Scrolling: Task list and timeline now scroll together vertically
  • Proper Height Constraints: Timeline view now respects viewport height
  • Improved Scrollbar Styling: Consistent thin scrollbars across both columns

Technical Improvements

  • Obsidian API Compliance: All file operations use proper Obsidian vault API
  • TypeScript Strict Mode: Full compliance with TypeScript strict type checking
  • Resource Cleanup: Proper cleanup of event listeners and animation frames
  • Build Verification: All code compiles without errors or warnings

[0.6.6] — 2026-01-25

Added

Settings

  • Projects Base Path Setting: New setting to control where project folders are created
  • Defaults to "Project Planner"
  • Allows organizing all projects under a common parent folder

Fixed

Dashboard View

  • Completed Task Filtering: Fixed completed tasks appearing in non-Completed cards (Critical Priority, High Priority, Overdue, Due Today, Due This Week)
  • All Projects Display: Fixed "Show All Projects" toggle not displaying tasks. Added getAllForProject() method to TaskStore
  • Bottom Stats Cards: Converted static stats to clickable KPI cards (High Priority, Has Dependencies, Not Started)
  • Task Status Updates: Added status badges to task modals with real-time updates

Grid View

  • Subtask Indentation: Fixed inconsistent indentation for subtasks. Consistent at 8px base + 20px per level

Markdown Sync

  • Auto-Create Task Notes: Fixed task notes not being created automatically. Added sync call to updateTask() method
  • Folder Creation: Fixed ENOENT errors — plugin now automatically creates parent folders
  • Bidirectional Sync: File watchers now use projectsBasePath setting for proper sync
  • Template Cleanup: Removed duplicate newline before footer separator

[0.6.5] — 2026-01-22

Added

Task Timestamps

  • Created Date Field: Tasks now track when they were created (auto-set on creation)
  • Last Modified Date Field: Tasks track when they were last updated
  • Smart Date Defaults: New tasks automatically set start date to today

Grid View Columns

  • Created Column: Shows task creation date (hideable, read-only)
  • Modified Column: Shows last modification date (hideable, read-only)
  • Both columns use monospace font and muted color for easy scanning

Changed

Date Format Improvements

  • Simplified Date Storage: Changed from ISO format (2026-01-15T00:00:00.000Z) to simple YYYY-MM-DD format
  • Cleaner data files, easier to read and edit manually
  • Maintains backward compatibility with old ISO format
  • Sync on Startup Default: Now defaults to false (was true) to prevent duplicate tasks with Obsidian Sync

Fixed

Plugin Startup Behavior

  • Removed Auto-Open on Startup: Plugin no longer automatically opens a tab when Obsidian starts
  • Views still restore from workspace state if previously open

Obsidian Sync Duplicate Prevention

  • Initial Sync Throttling: Added 5-minute cooldown between initial syncs
  • Increased Sync Lock Timeouts: Extended from 200ms to 1000ms for better Obsidian Sync handling
  • Batched File Processing: Initial sync now processes files with 100ms delays
  • Timestamp Preservation: Fixed lastModifiedDate being overwritten during sync
  • Sync on Startup Warning: Added clear warning in settings about Obsidian Sync
  • Better Duplicate Detection: Improved task ID matching to prevent re-imports

Technical

  • Added lastSyncTimestamp to PlannerProject interface for sync throttling
  • Enhanced TaskSync with better logging for debugging sync issues
  • Modified addTaskFromObject to preserve incoming timestamps
  • Added getTodayDate() helper function for consistent YYYY-MM-DD formatting
  • Updated TaskDetailView date input to handle both ISO and YYYY-MM-DD formats
  • Updated TaskSync YAML frontmatter to include createdDate and lastModifiedDate

[0.6.4] — 2026-01-20

Added

Card Preview Options

  • Card Preview Setting: New per-task setting in Task Details to control board card content
  • Hide: Default mode — no extra content on card
  • Show Checklist: Display inline checklist with interactive checkboxes directly on card
  • Show Description: Display task description with full Markdown rendering on card
  • Real-time synchronization between card and Task Details panel

Improved

Board View UI Enhancements (Microsoft Planner Style)

  • "Add Task" Button Positioning: Moved to top of bucket columns (matches MS Planner)
  • Tags now display at the very top of cards
  • Checkbox aligned on same row as task title
  • Cards align to top of bucket columns

Fixed

Code Quality & CSS Improvements

  • CSS Custom Properties: Added CSS variables for priority colors, status colors, and accent colors
  • Removed duplicate padding declarations and replaced 14 hardcoded color values with CSS variables
  • Removed 3 unnecessary !important declarations

Technical

  • Enhanced PlannerTask type with cardPreview property ("none" | "checklist" | "description")
  • Added MarkdownRenderer integration to BoardView for description rendering
  • Converted multiple BoardView rendering methods to async for Markdown rendering support

[0.6.3] — 2026-01-14

Added

Daily Note Task Tagging

  • Automatic Task Import from Daily Notes: Scan any markdown note for tagged tasks and import them into projects
  • Tag tasks with #planner to add to default project
  • Tag tasks with #planner/ProjectName to add to specific project
  • Real-time file watching detects new tasks as you create them
  • Smart Task Parsing: Automatically extracts priority (!!!, !!, !), due dates (📅 2026-01-20, due: 2026-01-20, @2026-01-20), tags, and completion status
  • New Settings Panel: "Daily Note Task Tagging" section with enable toggle, tag pattern, scan folders, default project, and manual scan button
  • Content-based unique IDs to prevent duplicates; re-importing updates existing tasks

Technical

  • DailyNoteTaskScanner: New utility class (src/utils/DailyNoteTaskScanner.ts) managing file watching, regex-based task detection, and duplicate prevention
  • TaskStore Enhancement: New addTaskToProject() method for adding tasks to specific projects
  • Four new settings: enableDailyNoteSync, dailyNoteTagPattern, dailyNoteScanFolders, dailyNoteDefaultProject

Documentation

  • daily_notes_tagging.md: Quick start, advanced usage, configuration, troubleshooting, and daily note template

Fixed

  • Improved project name matching to support both spaces and hyphens consistently
  • Added validation and error messages when default project is not configured

[0.6.2] — 2026-01-13

Added

Bidirectional Markdown Sync

  • Full Bidirectional Sync: Complete two-way synchronization between plugin JSON data and vault markdown notes
  • Tasks sync to individual markdown files in {ProjectName}/Tasks/ folders
  • YAML frontmatter contains all task metadata; markdown body includes description, subtasks, and links
  • Real-time automatic sync using metadata cache and vault event watchers
  • Markdown Content Parsing: Full parsing including descriptions, subtask checkbox lists, and wiki/external links
  • Sync Settings: enableMarkdownSync, autoCreateTaskNotes, syncOnStartup
  • Manual "Sync All Tasks Now" button in settings

Project Metadata Tracking

  • Created/Updated Timestamps: Projects now track creation and last updated dates
  • Dashboard shows project metadata with timestamps and task counts
  • Clickable project cards navigate to Grid view

UI Improvements

  • Filter Label Visibility: Active filters now show clear labels in Grid view header
  • Improved dashboard project card layout and metadata display

Fixed

  • Symmetric Sync: Markdown-to-plugin sync now captures all content (previously only YAML was synced back)
  • Live Sync: Watchers trigger automatically without requiring manual sync button clicks
  • Sync Loop Prevention: Set-based tracking prevents infinite sync loops

Technical

  • TaskSync Utility: New src/utils/TaskSync.ts class managing all sync operations
  • Primary event listener using metadataCache.on('changed') for reliable YAML detection
  • Backup watchers for file create, modify, and delete operations
  • syncInProgress Set with 200ms timeout to prevent circular updates

Documentation

  • MARKDOWN_SYNC.md: Complete guide to bidirectional sync, YAML format, and troubleshooting
  • Updated documentation with high-level descriptions of all six views

[0.6.1] — 2026-01-07

Added

  • View Tab Opening Behavior: New openViewsInNewTab setting — when disabled (default), views replace the active tab; when enabled, each view creates a new tab
  • Bucket Selection in Task Details: Dropdown selector to assign tasks to buckets from the task details panel
  • Bucket Column in Grid View: New hideable "Bucket" column for quick bucket assignment

Fixed

  • Workspace Initialization: Fixed plugin initialization error by waiting for workspace layout to be ready
  • Tab Reuse Logic: Corrected openViewsInNewTab setting behavior

[0.6.0] — 2026-01-07

Added

New Views

  • Dashboard View: New dashboard with KPI metrics and project overview (foundation for v0.7.0 KPI expansion)
  • Dependency Graph View: Visual representation of task dependencies with interactive graph visualization
  • Header Component: Reusable header component for consistent UI across views

Task Management

  • Bucket Selection in Task Details: Dropdown selector to assign tasks to buckets
  • Bucket Column in Grid View: New hideable column for quick bucket assignment
  • Project Hub Manager: New utility for creating and managing project hub notes

Settings & Configuration

  • View Tab Opening Behavior: New openViewsInNewTab setting

Infrastructure

  • GitHub Actions Release Workflow: Automated build and release process. Triggers on version tags, builds plugin, uploads artifacts for BRAT installation

Fixed

  • Workspace Initialization: Fixed plugin initialization error by waiting for workspace layout to be ready
  • Tab Reuse Logic: Corrected openViewsInNewTab setting behavior
  • Plugin Release Distribution: Added proper GitHub Actions workflow for BRAT compatibility

Changed

  • Grid View column system enhanced with new bucket column alongside existing columns
  • Task Detail Panel expanded with bucket selection interface

Technical

  • Enhanced TypeScript type definitions and interfaces
  • Better integration with Obsidian workspace APIs for view management
  • Improved build configuration with proper manifest handling

[0.5.0] — Previous Release

See the GitHub repository for previous changelog entries.


Upcoming Roadmap

  • v0.7.0: Dashboard KPI expansion and enhancements
  • v0.8.0: Core Obsidian plugin integrations
  • v0.9.0: UX/UI refinements and plugin settings
  • v1.0.0: Official release with stability improvements