Added

  • Ishikawa (fishbone) diagram view: create cause-and-effect diagrams with a problem statement, named cause categories, and sub-causes; rendered as an inline SVG fishbone with spine, angled bones, and sub-cause lines; stored as fishbone/*.md files with categories as ## Category / - subcause markdown sections
  • Fishbone API: GET/POST /api/fishbone, PUT /api/fishbone/:id, DELETE /api/fishbone/:id; default categories (People, Process, Machine, Material, Method, Measurement) pre-populated on create
  • Fishbone sidenav: view mode with full SVG diagram and cause/sub-cause counts; edit mode with title, description, and a markdown-format textarea for causes
  • Fishbone registered in feature visibility toggle (key: fishbone, group: Diagrams) and Cmd+K search
  • Habit Tracker: new view to define habits (daily or weekly), mark completions, track streaks, and view a 12-week calendar heatmap per habit; stored as habits/*.md files with completions as a flat date array in frontmatter
  • Habit streak logic: server-side calculation of current streak and all-time best streak on every read/write; weekly habits count consecutive weeks with at least one completion
  • Habit API: GET/POST /api/habits, PUT /api/habits/:id, POST /api/habits/:id/complete, DELETE /api/habits/:id/complete/:date, DELETE /api/habits/:id; mark-as-done is idempotent
  • Habit sidenav: view mode with full heatmap + streak stats, edit mode with name, description, frequency, target days (weekly), and notes (markdown)
  • Habits registered in feature visibility toggle (key: habits) and Cmd+K search
  • DNS Tracker: new view to track domain names, expiry dates, auto-renew status, renewal costs, nameservers, and notes; stored as dns/*.md files
  • DNS expiry color-coded badges: CRITICAL (<14d), URGENT (<31d), SOON (<61d), UPCOMING (<91d), OK; auto-renew flag shown as a shield icon
  • DNS batch actions: multi-select rows to set renewal cost or delete in bulk via a floating action bar
  • Cloudflare Registrar integration: sync domain expiry and auto-renew status from the Cloudflare API via “Scan from Cloudflare” button; sync contract enforced at the API level (only expiryDate, autoRenew, lastFetchedAt are written — renewalCostUsd, notes, and other manual fields are never overwritten)
  • Integration secrets infrastructure: POST/GET/DELETE /api/integrations/cloudflare stores Cloudflare API tokens in project.md
  • AES-256-GCM encryption for integration tokens: set MDPLANNER_SECRET_KEY (32-byte hex) to encrypt stored tokens; plaintext fallback when the key is not set; Settings shows an encryption status banner
  • mdplanner keygen-secret subcommand generates a random 32-byte hex key for use as MDPLANNER_SECRET_KEY
  • DNS domains indexed in SQLite FTS cache: domain and notes are searchable via the global Cmd+K overlay and /api/search
  • Backup system: GET /api/backup/export streams the project as a TAR archive; POST /api/backup/import extracts an archive into the project directory (pass ?overwrite=true to clobber existing files)
  • Backup encryption: start the server with --backup-public-key <hex> and all exports are encrypted with AES-256-GCM (key wrapped with RSA-OAEP-4096); no external dependencies — uses the built-in Web Crypto API (crypto.subtle)
  • mdplanner keygen subcommand generates a hex-encoded RSA-OAEP-4096 key pair and prints both keys; the public key goes to --backup-public-key, the private key is used as the X-Backup-Private-Key header when importing an encrypted archive
  • Automated backup scheduler: --backup-dir <path> combined with --backup-interval <hours> writes backup files to the given directory at the configured interval; env vars MDPLANNER_BACKUP_DIR, MDPLANNER_BACKUP_INTERVAL, MDPLANNER_BACKUP_PUBLIC_KEY are supported
  • POST /api/backup/trigger writes an on-demand backup to --backup-dir (requires --backup-dir to be set)
  • GET /api/backup/status returns last backup time, size, encryption flag, interval, and last error
  • Backup panel in the Settings view: export button, import file picker with optional private key input, manual trigger button, and status summary
  • backup feature toggle registered in feature visibility settings
  • GitHub integration: link tasks to GitHub issues (create issue from task sidenav, store issue URL in task frontmatter); link portfolio items to a GitHub repository (show stars, open issues, last commit); PAT stored encrypted in project.md; GitHub settings panel in Settings view
  • GET /api/integrations/github/test verifies the stored PAT by calling GET /user on the GitHub API
  • Global autofill/suggest utility (AutocompleteInput) applied to people fields across meetings, onboarding, and other free-text fields with known data sources
  • Multi-entity CSV export: GET /api/export/csv/:entity for tasks, notes, goals, meetings, people, and portfolio; export modal with JSON/CSV radio selector
  • Import preview modal: shows first 10 rows before confirming; per-row validation with structured error reporting ({imported, skipped, errors})
  • Cloudflare Registrar domain fetch now paginates (per_page=50) to retrieve all domains when an account has more than the default page size
  • Cloudflare settings panel now documents the required token permissions: Account Settings: Read (to resolve account ID) and Registrar: Read (to list domains)

Changed

  • Ideas view: added table/card view toggle (persisted in localStorage); added optional project field linking an idea to a portfolio item; both card and table views display the project as a badge
  • Idea sorter: font sizes raised to var(--font-size-sm) / var(--font-size-base) throughout
  • Milestones view: progress bar track has 1px solid var(--color-border-default) border; all text uses CSS font-size variables; delete button uses btn-danger-ghost error styling; card action buttons anchored to card bottom via margin-top: auto; optional project field added with badge display
  • Retrospective view: same delete button and font-size fixes as milestones
  • Meetings view: table/card view toggle (persisted in localStorage)
  • Habits calendar: prev/next month navigation arrows; hover tooltips showing habit name, date, and completion status; per-day notes (click a completed cell to add or edit a note, stored in day_notes frontmatter field)
  • DNS view: font sizes raised to CSS variables; “Add domain” button now opens the create sidenav correctly; edit sidenav now slides in correctly (inner .sidenav-panel receives the active class)
  • Settings view: GitHub default repository field removed (repo is now set per-task in the task sidenav)
  • Summary view: project start date parsed as local date (not UTC midnight) to avoid ±1 day timezone shift
  • DNS PUT route now performs a partial update — only fields present in the request body are written, preventing batch operations (e.g. set renewal cost) from overwriting unrelated fields such as Cloudflare-synced expiry and auto-renew data
  • Infrastructure nav group: DNS and GitHub entries grouped under a collapsible “Infrastructure” section in the desktop sidenav and mobile menu

Fixed

  • Cloudflare API token save bug: nested YAML objects (integrations.cloudflare) were not parsed correctly on read, causing getIntegrationSecret to always return null; fixed by extending parseYamlSimple to track pending nested object targets
  • parseInlineObject no longer splits on commas inside quoted strings, preventing corruption of values such as encrypted tokens that contain colons and commas
  • Copy-link toast now fires on both the Clipboard API success path and the execCommand fallback path
  • Section-move <select> added to list view task rows (was board-only)
  • WebDAV PROPFIND responses now include the correct /webdav path prefix in all <href> elements; DAV clients (Obsidian, Cyberduck) no longer navigate to wrong paths