This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is markdown-neuraxis, an experimental local-first tool for structured thought, life organization, and personal knowledge management built on plain Markdown files. The project combines inspiration from GTD, PARA method, Sunsama, Logseq, and Kanban into a cohesive markdown-first system.
Tim's personal journey through various tools (GTD+Trello → Sunsama → journalling → Logseq + wiki system) led to this unified approach. Key principles:
- Local-first, open source to avoid enshittification and vendor lock-in
- Markdown as single source of truth - plain text files that work everywhere
- Connects goals → tasks → notes into a coherent, navigable system
- Low friction capture & organization with flow over control
- Keyboard-first UX for speed and clarity
- Split views, not tabs to avoid cognitive load of hidden state
The project has evolved from documentation-only to working implementations on multiple platforms:
- GUI Framework: Switched from egui to Dioxus (see ADR-0001)
- Basic functionality: File browser, markdown parsing, outline display
- Build system: Rust with Dioxus desktop framework
- GUI Framework: Jetpack Compose with Material 3
- Functionality: File browser, markdown rendering, wiki-link navigation
- FFI Integration: UniFFI bindings to shared Rust parsing library
- Status: Read-only viewer with full wiki-link support
Task list lives in TASKS.md
Based on doc/methodology.md, the system supports:
- Daily journals:
journal/YYYY_MM_DD.mdfiles for flow-based capture - INBOX system: Universal capture with
INBOXprefixed bullets +0_Inbox/folder - Status tracking:
TODO,DOING,DONE,WAITING,SOMEDAYstates - Goal linking: UUID-based cross-references between files
((uuid)) - Daily planning: Sunsama-inspired daily triage and priority setting
notes/ # Markdown files can be anywhere in root
├── journal/ # Optional subfolder for journals
├── assets/ # Optional subfolder for assets
├── 0_Inbox/ # Universal capture folder
├── 1_Projects/ # Active projects
├── 2_Areas/ # Ongoing responsibilities
├── 3_Resources/ # Reference materials
├── 4_Archive/ # Completed/inactive items
└── any-folders/ # Complete flexibility
- Markdown parsing: Headings, bullets, code blocks, metadata (
property:: value) - Fractal outlines: Arbitrarily deep nesting, collapsible bullets
- Cross-linking:
[[wiki-links]]with backlink index and autocomplete - Tagging:
#tagsfor context and filtering - Query system:
query:: status:: DOINGfor dynamic dashboards - Kanban views: Visual WIP management inspired by Toyota Way
Shared Core (Rust):
- Markdown Parsing: Custom Rowan-based parser (
markdown-neuraxis-syntaxcrate) with lossless CST - Syntax Tree: Rowan library (from rust-analyzer) for red-green tree representation
- FFI: UniFFI for generating cross-platform bindings (Kotlin, Swift)
- Testing:
rstestfor parameterized tests,instafor snapshot testing,pretty_assertions
Desktop (Rust/Dioxus):
- GUI Framework: Dioxus desktop 0.6 (switched from egui, see ADR-0001)
- File System: Direct OS filesystem access
- State Management: In-memory signals for UI state
Android (Kotlin/Compose):
- Language: Kotlin 2.0
- GUI Framework: Jetpack Compose with Material 3
- FFI: JNA 5.15 for Rust library calls via UniFFI
- File System: Storage Access Framework (DocumentFile API)
- Min SDK: 29 (Android 10), Target SDK: 35 (Android 15)
crates/
├── markdown-neuraxis-syntax/ # Rowan-based Markdown parser (see ADR-0012)
│ └── src/
│ ├── lib.rs # Parser entry point: parse(source) -> SyntaxNode
│ ├── lexer.rs # Token-based lexer producing SyntaxKind tokens
│ ├── syntax_kind.rs # SyntaxKind enum (tokens + composite nodes)
│ └── parser/ # Recursive descent parser
│ └── grammar/ # Block and inline parsing rules
│
├── markdown-neuraxis-engine/ # Core editing model (ADR-0004)
│ └── src/
│ └── editing/
│ ├── document.rs # xi-rope buffer + Rowan parsing
│ ├── commands.rs # Edit command compilation (Cmd → Delta)
│ ├── anchors.rs # Stable block identity system
│ └── snapshot.rs # UI-ready Block tree projection
│
├── markdown-neuraxis-dioxus/ # Desktop GUI (Dioxus 0.6)
│ └── src/
│ ├── ui/app.rs # Main App component
│ └── ui/components/ # Block renderers, editor, file browser
│
├── markdown-neuraxis-ffi/ # UniFFI bindings for mobile
├── markdown-neuraxis-cli/ # CLI entry point
└── markdown-neuraxis-config/ # Configuration management
Layer Separation Rule: ALL parsing logic belongs in markdown-neuraxis-syntax. The snapshot layer (snapshot.rs) only projects/transforms the syntax tree into UI types - it must NOT perform any parsing or syntax detection. The UI layer renders what it's given. If you find yourself detecting syntax patterns in snapshot or UI code, that logic belongs in the parser.
android/
├── app/src/main/java/co/rustworkshop/markdownneuraxis/
│ ├── MainActivity.kt # Entry point, navigation, state management
│ ├── ui/
│ │ ├── screens/
│ │ │ ├── SetupScreen.kt # Initial folder selection
│ │ │ ├── FileListScreen.kt # File browser with tree view
│ │ │ ├── FileViewScreen.kt # Markdown content viewer
│ │ │ └── MissingFileScreen.kt # Broken wiki-link placeholder
│ │ ├── components/
│ │ │ ├── AppBottomBar.kt # Bottom nav with menu/home
│ │ │ ├── AppDrawer.kt # Navigation drawer
│ │ │ ├── FileTreeNodeItem.kt # Expandable tree items
│ │ │ └── StatusToast.kt # Scanning progress overlay
│ │ └── theme/Theme.kt # Solarized color scheme
│ ├── model/FileTree.kt # Hierarchical file tree structure
│ ├── io/
│ │ ├── FileScanner.kt # High-performance directory scanning
│ │ └── Preferences.kt # URI persistence via SharedPreferences
│ └── uniffi/markdown_neuraxis_ffi/ # Auto-generated Rust FFI bindings
├── app/build.gradle.kts # App configuration (SDK 29-35)
├── gradle/libs.versions.toml # Dependency versions (Compose 2024.12)
└── lint.xml # Lint rules for UniFFI compatibility
- Framework: Jetpack Compose with Material 3 design system
- FFI: UniFFI-generated Kotlin bindings via JNA to shared Rust library
- State: Composable state with file stack for navigation history
- Storage: Storage Access Framework (SAF) with DocumentFile API
- Performance: Cursor-based directory queries, batch processing, file caching
- ✅ Folder selection with persistent URI permissions
- ✅ Progressive file scanning with real-time UI updates
- ✅ Hierarchical file browser with expand/collapse
- ✅ Markdown rendering (headings, lists, code blocks, quotes)
- ✅ Wiki-link resolution and navigation
- ✅ URL click handling (opens external browser)
- ✅ Pull-to-refresh scanning
- ✅ Dark/light theme support (Solarized)
- ❌ File editing (not yet implemented)
- ❌ Search functionality (not yet implemented)
- Startup: CLI validates notes directory structure via
io::validate_notes_dir() - File Discovery:
io::scan_markdown_files()recursively finds.mdfiles in notes root directory - File Selection: User clicks file →
io::read_file()→Document::from_bytes() - Parsing:
markdown_neuraxis_syntax::parse()produces lossless RowanSyntaxNodetree - Snapshot:
Document::snapshot()projects syntax tree into UI-readyBlocktree with:BlockKind(Heading, Paragraph, List, ListItem, etc.)InlineSegments for formatted text (emphasis, links, wiki-links)- Stable
AnchorIds for focus tracking across edits
- Rendering: Dioxus
BlockRendererrecursively rendersBlocktree to HTML - Editing: Focus block → show raw source in textarea →
Cmd→Delta→ re-parse
- Current: Static internal plugins via traits (compile-time)
- Future: WASM-based dynamic plugins for third-party extensibility
- Examples: Inbox aggregation, goal tracing, PARA dashboards, file importers
- Split views, not tabs - Sidebar file browser + main content panel
- Keyboard-first - Fast navigation and editing
- Local-first - No cloud dependencies in MVP
- Plain text primacy - Markdown files remain readable outside the app
- ✅ CLI Interface: Single argument for notes folder path
- ✅ File Browser: Recursive markdown file discovery and selection
- ✅ Markdown Parsing: Hierarchical bullet point outline extraction
- ✅ UI Layout: Sidebar + main content with Solarized Light theme
- ✅ Error Handling: Graceful validation and error display
- ✅ Testing: Snapshot tests for outline parsing, unit tests for core logic
- Follow the standardized workflow: See
doc/claude-workflow.mdfor the complete development process - Uses specialized agents (feature-implementor, code-reviewer) for complex changes
- Simple changes (typos, single-line fixes) can skip the full workflow
- All commits must have passing tests, be formatted, and include prompt history
Desktop (Rust/Dioxus):
- System dependencies for Dioxus desktop (WebKit, GTK, etc.)
- See
doc/development.mdfor full setup instructions - Run
./dev-setup.shfor automated Ubuntu/Debian setup
Android:
- Android Studio with SDK 35
- JDK 11+
- UniFFI library built for target architecture (ARM64/x86_64)
- Run
./lint.shto check both Rust and Android linting
- Outside-in integration tests for all features (as per design doc)
- Unit tests for modules/functions as needed
- No feature should be deliverable without passing tests
- Licensed under AGPL v3
- Core tooling will remain AGPL
- May provide additional paid services (e.g. email-to-inbox bridge)
- Explicitly avoids duplicating well-solved problems (file sync, etc.)
- Install system dependencies (see
doc/development.md) - Clone the repository
- Run:
cargo run <path-to-notes-folder> - The app will open showing markdown files from the notes root directory
The executable takes a single argument - path to the root notes folder. Markdown files can be organized anywhere within this directory using any folder structure you prefer.
- Open the
android/directory in Android Studio - Build the UniFFI library:
cargo build --release --features ffi - Copy the native library to
android/app/src/main/jniLibs/ - Build and run from Android Studio
- On first launch, select your notes folder via the document picker