Ordered plan for building the unofficial mobile CherryTree-style notes app. Check items as they land on main (or your release branch). For versioning history, see CHANGELOG.md.
Legend: [x] done · [ ] not started · [-] in progress (optional; use sparingly)
- App version lives in
pubspec.yamlasversion: MAJOR.MINOR.PATCH+BUILD(Flutter convention:+BUILDis the store build number). - Early stage: use 0.x.y until the app is Play Store / App Store ready; then move to 1.0.0+ and keep SemVer. Details:
CHANGELOG.md. - Changelog entries should match tagged releases when you tag them in Git.
- Prefer small, reviewable PRs that map to one or two items below.
- GPLv3 +
LICENSE/ attribution / README disclaimer (not the official CherryTree app) - Android + iOS only (no web/desktop Flutter targets in this repo)
- Document bundle IDs and dev workflow (
README.md,DEVELOPMENT_GUIDELINES.md)
Goal: trustworthy tree + editor + persistence on device, without CherryTree file formats yet.
- Hierarchical notes (tree) + title/body editor
- Local JSON persistence under app documents (
NoteRepository,spike_a_notes.json) - First-run seed note (localized via device locale where applicable)
- Debounced save for typing; immediate save for structural changes; flush on app pause / dispose
- Drawer + wide layout; fix nested scroll / safe-area issues on phones
- Android edge-to-edge / system bars: landscape (and similar) layouts must not draw under the on-screen Back / Home / Recents strip when the OS reports weak or zero nav insets to Flutter — handled in native
MainActivityviaWindowInsetsCompaton the content root (seeCHANGELOG.md).
-
flutter analyzeclean; unit tests forNoteDocument+NoteRepository(injected file path) - gen-l10n (EN / NL / DE), theme tokens (spacing, colors, timing)
-
integration_teston Android (and iOS when feasible): load → edit → background → relaunch - Save/error feedback UX (e.g. subtle status or retry) beyond snackbar on hard failures
- Split oversized widgets if any file grows past ~300 lines (see
AGENTS.md)
- Export to CherryTree
.ctd/.ctb(app bar save as → format sheet → system save dialog;CherrytreeDocumentExport) - Round-trip parity with desktop CherryTree files
- Map upstream storage formats (reference:
lib/cherrytree/readers; upstreamct_storage_xml/ct_storage_sqlitein giuspen/cherrytree) - Read-only import of a narrow subset: unencrypted
.ctd(XML) and.ctb(SQLite); body text fromrich_text/ plain nodes (images, tables, code boxes omitted with messaging) - Clear UX when a feature is unsupported (replace-data confirmation, post-import warnings, encrypted
.ctz/.ctxrejected)
- Import file picker: AppBar folder action opens the OS file picker (
FilePicker+ replace/import flow). On Android 11+,AndroidManifest.xmlmust declare an<queries>intent forOPEN_DOCUMENTsoresolveActivitycan see the system document UI;MainActivityextendsFlutterFragmentActivity. (Previously tracked as GitHub #1, now closed.) On iOS, useFileType.anyand validate.ctd/.ctbin Dart —FileType.custom+ those extensions maps to UTIsfile_pickerdiscards, which greys out files in OneDrive and similar providers. - Tree expand/collapse in the notes panel (chevrons) so large imports are easier to navigate.
- Path breadcrumbs (or subtitle) for the selected node — AppBar
bottomstrip,NoteDocument.pathFromRoot,/join (seeCTAppBar.breadcrumbPath). - Optional dark theme —
AppTheme.dark()(navy scaffold viaAppColors.darkScaffold),SettingsPageswitch, preferenceuse_dark_themeinshared_preferences(lib/app/app_settings.dart). Further CherryTree-like prefs can use the same screen (categories later). - Split Screen Portrait Layout —
SettingsPagetoggle to render the note tree above the bottom editor explicitly globally on portrait screens. - Language Selector — Settings feature overriding standard app locale (EN, NL, DE, or System overrides) gracefully through
SharedPreferences. - Richer body (phase 1) — body
TextFielduses monospace, stable line height (StrutStyle), filled outline field; title stays proportional (seeNodeEditor). - Richer body (phase 2): checklist widgets, syntax / rich text — after Spike C or as a dedicated spike.
- Save back without corrupting documents that desktop CherryTree can still open
- Automated checks against reference exports / fixtures
- Encryption, multifile storage, attachments, rich text — only after narrow round-trip is proven
- Store listings, signing, CI release automation (as needed)
Cross-check desktop behaviour against the CherryTree User Manual (giuspen.net/cherrytreemanual, mirror giuspen.com/cherrytreemanual) and the reference C++ sources in giuspen/cherrytree (notably src/ct/ct_treestore.h CtNodeData, src/ct/ct_config.h CtConfig). The HTML manual may lag the current app; confirm renamed or new features in upstream when implementing.
A broader feature narrative (third-party checklist) lives in EXTENSIVE_LIST.md; rows below remain the authoritative T/L/S tracking tables. Merge new ideas from EXTENSIVE_LIST.md here when you commit to implementing them.
Triage tags (this section only):
| Tag | Meaning |
|---|
| T | Target for this Flutter app — use - [ ] / - [x] when tracking backlog. |
| L | Later — desirable parity but blocked on spikes, editor depth, or scope. |
| S | Skip — desktop-only or explicitly out of scope for mobile unless revisited. |
Only T rows use task checkboxes so L / S items do not imply commitment.
Fields in CtNodeData (persistence for ordinary nodes; shared-node fields omitted here): nodeId, sequence, name, syntax, tags, isReadOnly, customIconId, isBold, excludeMeFromSearch, excludeChildrenFromSearch, foregroundRgb24, tsCreation, tsLastSave, plus text buffer / anchored widgets for body content.
| Feature | Tag | Notes |
|---|
| Node name | T | [x] NoteNode.title |
| Bold title in tree | T | [ ] not in NoteNode; XML is_bold not round-tripped |
| Custom title color | T | [ ] foregroundRgb24 |
| Custom stock icon | T | [x] import + tree display customIconId; [ ] in-app picker + edit properties UI |
| Node type: rich / plain / code + language | L | syntax; Spike B reads; editor is rich-first |
| Tags for search | T | [ ] tags |
| Read-only | T | [ ] isReadOnly |
| Exclude this node / subnodes from search | L | excludeMeFromSearch, excludeChildrenFromSearch |
| Unique id (read-only in dialog) | S | informational; maps to storage ids |
| Feature | Tag | Notes |
|---|
| Add sibling / subnode | T | [x] structural actions in app (verify parity with desktop semantics) |
| Rename node title | T | [x] NodeEditor title field (not tree inline-F2) |
| Duplicate node | L | |
| Bookmarks add/remove | L | |
| Insert today’s node | S | desktop convenience; optional L |
| Tree info (counts) | L | |
| Move up/down/left/right, change parent | L | drag reorder S on mobile; buttons L |
| Sort tree / sort branch | L | |
| Find / replace in node names and tags | L | |
| Inherit syntax from parent | L | code nodes |
| Delete node | T | [x] |
| Selection history back/forward | L | |
| Feature | Tag | Notes |
|---|
| New / open / recent | L | mobile uses JSON + import; full “recent docs” L |
| Save / Save As | L | Spike C writes .ctd/.ctb |
| SQLite vs XML, .ctx/.ctz encrypted | L | encryption Later (see Spike C / Later) |
| Save and Vacuum (SQLite) | L | |
| Password change via Save As | L | |
| Page setup / print | S | |
| Import from other apps (HTML, folder, …) | L | narrow import may stay CherryTree-only |
| Export PDF/HTML/txt/CT | L | |
| CLI open/export | S | |
| Feature | Tag | Notes |
|---|
| Plain / rich / syntax node bodies | L | rich path via Quill; plain/code L | | Editing, formatting, lists, etc. | L | rich text phase 2; see Spike B omissions | | Search in node content (manual §7.6) | L | |
| Feature | Tag | Notes |
|---|
| Case-sensitive / match whole word / regex | L | | | Scope: current node, node + subnodes, whole tree | L | | | Replace in body (incl. multi-node / batch) | L | | | Replace in node names / tags (see tree ops) | L | overlaps “Find in node names” |
Items called out in EXTENSIVE_LIST.md that are not spelled out in the tables above; L unless the app explicitly skips them (S).
| Feature | Tag | Notes |
|---|
| Rich text headers H4–H6 (not only H1–H3) | L | desktop supports scalable tags | | Table: column sort; export table to CSV | L | | | Image: rotate; save image as PNG | L | import of images partial | | Multifile XML (document as folder) | L | multifile storage in “Later” | | Focus / distraction-free mode (hide tree or toolbar) | L | mobile layout differs | | Extensive keyboard shortcut map (tablet + keyboard) | L | optional cheat sheet | | Inter-app copy/paste preserving rich text | L | strong mobile UX target | | Competitor imports (KeepNote, Zim, Tomboy, …) | L | CherryTree-only import for now |
| Feature | Tag | Notes |
|---|
| Images | L | import warns / omits | | Tables | L | | | Codebox | L | | | Embedded files | L | | | Links (web, file, node, folder) | L | partial rich handling | | Anchors, TOC, timestamps, special chars, horizontal rule | L | |
Text & code (§9.1–9.4): tab width, spaces/tabs, wrapping, indent, line numbers, vertical spacing, timestamp format, horizontal rule, special chars, double-click word chars, smart quotes, symbol replace, spell check, RT/PT themes, whitespace / current line / codebox / embedded file / undo limit, PT/code style schemes, code execution + terminal — mostly L; spell check L; execution S on mobile.
Tree (§9.5–9.6): tree light/dark/custom colors; default node icons (cherries per level / single icon / none) — T partial (CherrytreeNodeIconTheme, [ ] load in UI + Settings); aux icon hide; restore expand/collapse; expand all / collapse all; bookmarks visible — L (expand state [x] session-only); tree right side S/minimal L; click-to-focus text, click-to-expand — L; last visited nodes in header S.
Fonts (§9.7): RT/PT/code/tree fonts — L (mobile system + theme tokens first).
Links (§9.8): custom actions, link colors, underline, relative paths, anchor size — L.
Toolbar (§9.9): configurable toolbar — S.
Keyboard shortcuts (§9.10): — L (platform conventions; optional cheat sheet).
Misc (§9.11): autosave, backups, systray, proxy, word count, etc. — L / S as appropriate (autosave [x] app debounce; backup copies L).
| Manual § | Topic |
|---|
| 4 | Quick start: interface, node management, insert objects, save, export | | 5 | Files: open/save, vacuum, storage types, password, print, import/export formats, CLI | | 6 | Nodes: create properties, manage tree | | 7 | Text: plain, rich, syntax highlighting, editing, formatting, search | | 8 | Objects: images, tables, codebox, files, links, anchors, TOC, timestamps, … | | 9 | Settings: text/code, tree, fonts, links, toolbar, shortcuts, misc |
When you complete a step, turn [ ] into [x] in the same PR as the code change, and add a short note under CHANGELOG.md Unreleased (or the release section you are cutting).
Parity inventory: Rows in CherryTree parity inventory follow the same rule: when a T item is implemented, set its checkbox to [x] in the same PR and mention the behaviour in Unreleased. If the manual and code disagree, prefer CtNodeData / CtConfig and add a short note in the table. Re-skim the manual or upstream on major CherryTree releases if parity matters. Narrative checklists such as EXTENSIVE_LIST.md should be merged into the parity tables when work is scheduled, not left as a second source of truth for T/L/S.