- Add CodeMirror 6 with oneDark theme and markdown language support
- Bundle via esbuild into public/vendor/ (built on deploy, not committed)
- Add codemirror-entry.mjs as bundle entry point
- Fix SPA fallback to only serve index.html for /, not all paths
- Fix mime type handling by mutating mime-types registry
- Add Write/Preview tabs; preview renders on tab switch only
- Multi-cursor via Shift+Alt+Up/Down; Alt+Click adds cursor
- gitignore package-lock.json and public/vendor/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove Entry_Dialog class; edit/new now navigate to #edit/<id> and #new/...
- render_edit_view() builds a full-page layout: header with title input,
Write/Preview tabs, and a metadata sidebar
- Tab key inserts a literal tab character in the editor
- Ctrl+S saves from both title input and textarea
- Body/main element uses flex column layout so edit view fills viewport
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
display:none removes element from grid flow, shifting other columns.
Use visibility:hidden instead so the expand button always holds its cell.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- expand | meta (type/id/status/priority stacked) | main (title/body/footer)
- Tags and actions in a .task-footer row inside .task-main
- Title now gets full remaining width
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- [hidden] { display: none !important } prevents CSS display overriding
the hidden attribute
- Clicking a tag chip in an entry row filters by that tag
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- #<number> navigates to a full detail view (rendered title + body,
meta badges, parent link, children list, edit/delete/sub buttons)
- Clicking entry row main area navigates to detail instead of opening edit
- Edit dialog remains for editing, delete redirects back to list
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Storage: nested object buckets per type, integrated next_id into meta,
migration from old flat task:N key format, seeded default types (task/idea/note)
- Server: /api/entry-types CRUD + /api/entries replacing /api/tasks, type
validation, blocks deletion if entries exist
- Frontend: dynamic nav per type, Entry_Type_Dialog, Entry_Dialog with type
selector, type chip in All view, Manage Types view
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Flat mode is now truly flat — no --depth CSS variable set on rows
and the flat-mode padding-left rule removed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Segmented control (Tree | Flat) replaces the toggle button
- Expand arrow hidden in flat mode
- Arrow listener only attached in tree mode
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- parent_id on tasks; roots shown by default, others expandable
- Expand/collapse per node with expand/collapse button
- Sub button creates subtask directly from the row
- Make subtask of button in edit dialog with searchable picker
- Remove parent clears the parent link in the dialog
- Flat mode toggle shows all tasks indented by depth
- Tree filter shows nodes whose descendants match, not only direct matches
- Deletion blocked if task has subtasks (client + server)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New /api/render-markdown proxy to Gitea (configured via config.yaml)
- lib/config.mjs loads config.yaml with yaml-js
- Edit/Preview tabs on the body field in the task dialog
- Title and body rendered as markdown inline in the task list
- Gitea markup+chroma CSS extracted and vendored to public/gitea-markup.css
- Markdown cached in memory per text string
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Node.js + Express 5 backend with flat NDJSON key-value store (borrowed from
electronics-inventory). Sequential integer IDs per namespace. Vanilla JS SPA
with filters for status, priority, and tags.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>