Skip to content
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