### Initial Setup and Run LazyNote on Windows Source: https://github.com/wyi1223/lazylife/blob/main/docs/development/windows-quickstart.md Commands to run from the repository root to set up dependencies, generate bindings, and launch the LazyNote Flutter application on Windows. This includes running diagnostic scripts and Flutter commands. ```powershell powershell -NoProfile -ExecutionPolicy Bypass -File scripts/doctor.ps1 -SkipFlutterDoctor powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gen_bindings.ps1 cd apps/lazynote_flutter; flutter pub get flutter run -d windows ``` -------------------------------- ### Install Tooling Prerequisites (PowerShell) Source: https://github.com/wyi1223/lazylife/blob/main/docs/releases/v0.2.5/prs/PR-0254B-architecture-baseline-tooling-implementation.md Installs the necessary command-line tools for generating architecture baseline artifacts. It pins specific versions to ensure reproducibility and requires a locked installation. ```powershell cargo install cargo-modules --version 0.25.0 --locked cargo install cargo-bloat --version 0.12.1 --locked dart pub global activate lakos 2.0.6 ``` -------------------------------- ### Installation Rules for Runtime Components Source: https://github.com/wyi1223/lazylife/blob/main/apps/lazynote_flutter/windows/CMakeLists.txt Configures the installation process for the application executable, ICU data, Flutter library, bundled plugin libraries, and native assets. It ensures files are placed correctly for in-place execution. ```cmake set(BUILD_BUNDLE_DIR "$") set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) if(PLUGIN_BUNDLED_LIBRARIES) install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") install(DIRECTORY "${NATIVE_ASSETS_DIR}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Flutter Assets Installation Source: https://github.com/wyi1223/lazylife/blob/main/apps/lazynote_flutter/windows/CMakeLists.txt Installs Flutter assets by first removing any existing assets and then copying the new ones from the build directory to the installation data directory. ```cmake set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) ``` -------------------------------- ### v0.1 Settings Schema Example (JSON) Source: https://github.com/wyi1223/lazylife/blob/main/docs/architecture/settings-config.md An example of the v0.1 schema for the `settings.json` file, illustrating the structure for entry, logging, and UI configurations. This schema defines default values and expected data types for various settings. ```json { "schema_version": 1, "entry": { "result_limit": 10, "use_single_entry_as_home": false, "expand_on_focus": true, "ui": { "collapsed_height": 72, "expanded_max_height": 420, "animation_ms": 180 } }, "logging": { "level_override": null }, "ui": { "language": "system" } } ``` -------------------------------- ### Build Windows Release Bundle for LazyNote Source: https://github.com/wyi1223/lazylife/blob/main/docs/development/windows-quickstart.md Command to execute from the repository root to create a distributable release bundle for the LazyNote Windows application. This script generates the executable, DLL, and zip archives. ```powershell powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build_windows_release_bundle.ps1 ``` -------------------------------- ### AOT Library Installation Source: https://github.com/wyi1223/lazylife/blob/main/apps/lazynote_flutter/windows/CMakeLists.txt Installs the Ahead-Of-Time (AOT) compilation library into the data directory, but only for 'Profile' and 'Release' build configurations. ```cmake install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" CONFIGURATIONS Profile;Release COMPONENT Runtime) ``` -------------------------------- ### Run LazyNote Diagnostics on Windows Source: https://github.com/wyi1223/lazylife/blob/main/docs/development/windows-quickstart.md A set of commands to run diagnostic checks for the LazyNote application on Windows. These include running the doctor script, checking code formatting, generating bindings, and executing smoke tests. ```powershell powershell -NoProfile -ExecutionPolicy Bypass -File scripts/doctor.ps1 powershell -NoProfile -ExecutionPolicy Bypass -File scripts/format.ps1 -Check powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gen_bindings.ps1 scripts\run_windows_smoke.bat ``` -------------------------------- ### Adding Database Migration Source: https://github.com/wyi1223/lazylife/blob/main/AGENTS.md Procedure for creating and registering new database migrations. Emphasizes creating new migration files, registering them in the mod.rs file, and the importance of not modifying existing migrations. ```text 1. Create: crates/lazynote_core/src/db/migrations/000N_description.sql - Next number is 10 (9 exist) 2. Register in: crates/lazynote_core/src/db/migrations/mod.rs - Add to MIGRATIONS array 3. NEVER modify existing migration files 4. Update: docs/architecture/data-model.md ``` -------------------------------- ### List Timed Atoms for Reminders (Rust & Dart) Source: https://context7.com/wyi1223/lazylife/llms.txt The `atoms_list_timed()` API fetches all active atoms that have either a start or end time set, excluding those marked as done or cancelled. This is crucial for bulk reminder scheduling when an application starts. The Rust FFI function retrieves the data, and the Dart example illustrates how to iterate through the timed atoms and schedule corresponding reminders. ```rust // Rust FFI #[flutter_rust_bridge::frb] pub async fn atoms_list_timed() -> AtomListResponse { // Returns all active atoms where start_at OR end_at is set // Excludes done/cancelled // No pagination - returns all matching atoms } ``` ```dart // Flutter usage - reminder recovery on app startup final timedAtoms = await rust_api.atomsListTimed(); for (final atom in timedAtoms.items) { if (atom.startAt != null) { // Schedule reminder for start time await scheduleReminder( atomId: atom.atomId, triggerTime: DateTime.fromMillisecondsSinceEpoch(atom.startAt!), title: atom.title, ); } } ``` -------------------------------- ### Dart Request Deduplication Logic Source: https://github.com/wyi1223/lazylife/blob/main/AGENTS.md Example of how Flutter controllers prevent stale responses by using a monotonic request ID. If the current request ID does not match the latest one, the response is discarded. ```dart final myRequestId = ++_requestId; final result = await invoker(...); if (myRequestId != _requestId) return; // Stale, discard ``` -------------------------------- ### Build Rust FFI for LazyNote Source: https://github.com/wyi1223/lazylife/blob/main/docs/development/windows-quickstart.md Instructions to build the Rust Foreign Function Interface (FFI) for LazyNote if a 'Failed to load dynamic library' error occurs. This involves navigating to the crates directory and building the lazynote_ffi package in release mode. ```powershell cd crates cargo build -p lazynote_ffi --release cd .. cd apps/lazynote_flutter flutter clean flutter pub get flutter run -d windows ``` -------------------------------- ### Query Calendar Events and Update Event Times (Rust & Dart) Source: https://context7.com/wyi1223/lazylife/llms.txt Provides APIs for fetching calendar events within a specified date range and for updating the start and end times of existing events. The Rust FFI functions `calendar_list_by_range` and `calendar_update_event` handle the backend logic, while the Dart examples demonstrate how to use these functions in a Flutter application for viewing events and rescheduling them. ```rust // Rust FFI #[flutter_rust_bridge::frb] pub async fn calendar_list_by_range( start_ms: i64, end_ms: i64, limit: Option, // default: 50, max: 50 offset: Option, ) -> AtomListResponse { // Returns atoms with start_at AND end_at that overlap range // Includes done/cancelled events (shown on calendar) } #[flutter_rust_bridge::frb] pub async fn calendar_update_event( atom_id: String, start_ms: i64, end_ms: i64, // Must be >= start_ms ) -> EntryActionResponse {} ``` ```dart // Flutter usage // Get week view events final weekStart = DateTime(2024, 3, 11); final weekEnd = DateTime(2024, 3, 17, 23, 59, 59); final events = await rust_api.calendarListByRange( startMs: weekStart.millisecondsSinceEpoch, endMs: weekEnd.millisecondsSinceEpoch, limit: 50, offset: 0, ); for (final event in events.items) { final start = DateTime.fromMillisecondsSinceEpoch(event.startAt!); final end = DateTime.fromMillisecondsSinceEpoch(event.endAt!); print('${event.title}: $start - $end'); } // Reschedule event (drag-and-drop) await rust_api.calendarUpdateEvent( atomId: 'a1b2c3d4-e5f6-...', startMs: DateTime(2024, 3, 16, 10, 0).millisecondsSinceEpoch, endMs: DateTime(2024, 3, 16, 12, 0).millisecondsSinceEpoch, ); ``` -------------------------------- ### Run Rust and Flutter Gates and Build Windows Bundle Source: https://github.com/wyi1223/lazylife/blob/main/docs/releases/v0.2/CLOSURE_KIT.md Executes Rust formatting, linting, and tests, followed by Flutter analysis and tests. It also initiates the Windows distributable packaging script. ```powershell cd crates cargo fmt --all -- --check cargo clippy --all -- -D warnings cargo test --all cd ..\apps\lazynote_flutter flutter analyze flutter test powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build_windows_release_bundle.ps1 ``` -------------------------------- ### Logging Initialization API (Flutter Usage) Source: https://context7.com/wyi1223/lazylife/llms.txt Demonstrates the Flutter bootstrap usage for initializing logging via the Rust FFI. It checks for success or failure and prints relevant information. ```dart // Assuming RustBridge is defined elsewhere and handles bootstrapLogging // final snapshot = await RustBridge.bootstrapLogging(); // if (snapshot.isSuccess) { // print('Logging initialized at level: ${snapshot.level}'); // print('Log directory: ${snapshot.logDir}'); // } else { // print('Logging failed: ${snapshot.errorMessage}'); // } ``` -------------------------------- ### Query Calendar Events by Time Range Source: https://github.com/wyi1223/lazylife/blob/main/docs/api/ffi-contracts.md Retrieves calendar events that overlap with a specified time range. It requires start and end timestamps in milliseconds and supports optional limit and offset for pagination. The query ensures that events with both start and end times are considered, and the overlap condition is `start_at < end_ms AND end_at > start_ms`. Results are ordered by start time, then end time. ```rust /// Returns atoms with both `start_at` and `end_at` set that overlap the given time range /// Overlap condition: `start_at < end_ms AND end_at > start_ms` /// Includes all statuses (done/cancelled shown on calendar) /// Order: `start_at ASC, end_at ASC` /// Reuses `AtomListResponse` / `AtomListItem` types from tasks APIs /// Default limit: `50`, max: `50` fn calendar_list_by_range(start_ms: i64, end_ms: i64, limit?: u32, offset?: u32) -> AtomListResponse; ``` -------------------------------- ### Timed Atoms Query for Reminders Source: https://context7.com/wyi1223/lazylife/llms.txt Retrieve all active atoms that have either a start time or an end time set. This is primarily used for bulk scheduling of reminders when an application starts. ```APIDOC ## GET /atoms/timed ### Description Fetches all active atoms that have time-related fields (start_at or end_at) populated. This endpoint is optimized for retrieving data needed for reminder systems, especially during application startup. It excludes completed or cancelled items and does not support pagination. ### Method GET ### Endpoint /atoms/timed ### Parameters None ### Response #### Success Response (200) - **items** (array) - A list of timed atom objects. - **atomId** (string) - The unique identifier for the atom. - **title** (string) - The title of the atom. - **startAt** (integer, optional) - The start time in milliseconds. - **endAt** (integer, optional) - The end time in milliseconds. #### Response Example { "items": [ { "atomId": "b2c3d4e5-f6a7-8901-2345-67890abcdef1", "title": "Follow-up Call", "startAt": 1710610000000 } ] } ``` -------------------------------- ### Entry Creation APIs Source: https://github.com/wyi1223/lazylife/blob/main/docs/releases/v0.1/prs/PR-0009A-entry-ffi-surface.md Provides FFI APIs for creating new entries, including notes and tasks, with specific default behaviors. ```APIDOC ## POST /api/entry_create_note ### Description Creates a new note entry with the provided content. ### Method POST ### Endpoint `/api/entry_create_note` ### Parameters #### Request Body - **content** (string) - Required - The content of the note. ### Request Example ```json { "content": "This is the content of the new note." } ``` ### Response #### Success Response (200) - **status** (string) - The status of the operation (e.g., `ok`). - **message** (string) - Optional - A message confirming the creation. #### Response Example ```json { "status": "ok", "message": "Note created successfully." } ``` ## POST /api/entry_create_task ### Description Creates a new task entry with the provided content. The task will have a default status of 'todo'. ### Method POST ### Endpoint `/api/entry_create_task` ### Parameters #### Request Body - **content** (string) - Required - The content of the task. ### Request Example ```json { "content": "Complete the FFI documentation." } ``` ### Response #### Success Response (200) - **status** (string) - The status of the operation (e.g., `ok`). - **message** (string) - Optional - A message confirming the creation. #### Response Example ```json { "status": "ok", "message": "Task created successfully." } ``` ``` -------------------------------- ### New Rust Service Method Implementation Source: https://github.com/wyi1223/lazylife/blob/main/AGENTS.md Illustrates the pattern for adding a new method to a Rust service. It shows the placement of the service method in `lazynote_core`, the corresponding FFI function in `lazynote_ffi`, and the binding regeneration step. ```rust // 1. In crates/lazynote_core/src/service/.rs: pub fn your_method(&self, ...) -> Result { // Call repo methods, apply business rules } // 2. In crates/lazynote_ffi/src/api.rs: #[flutter_rust_bridge::frb] pub async fn your_ffi_function(...) -> YourResponse { your_ffi_function_impl(...) } fn your_ffi_function_impl(...) -> YourResponse { // Open DB, create repo, create service, call method // Return typed envelope } // 3. Run: scripts/gen_bindings.ps1 ``` -------------------------------- ### Create Notes with Rust and Dart Source: https://context7.com/wyi1223/lazylife/llms.txt APIs for creating new note atoms. `entry_create_note` creates a note at the root level, while `note_create` allows specifying a parent folder. Both return responses indicating success and relevant item IDs. ```rust // Rust FFI - Simple creation via entry command #[flutter_rust_bridge::frb] pub async fn entry_create_note(content: String) -> EntryActionResponse { // Creates note at root level // Returns: ok, atom_id, node_uuid, message } // Full creation with parent folder #[flutter_rust_bridge::frb] pub async fn note_create( content: String, parent_node_id: Option, // Folder UUID or None for root ) -> AtomItemResponse { // Returns full atom data with node_uuid } ``` ```dart // Flutter usage - Simple creation final result = await rust_api.entryCreateNote(content: '# Meeting Notes\n\nDiscussed Q4 goals.'); if (result.ok) { print('Created note: ${result.atomId}'); print('Workspace node: ${result.nodeUuid}'); } else { print('Failed: ${result.message}'); } // Creation in specific folder final noteResult = await rust_api.noteCreate( content: '# Project Ideas\n\nNew feature brainstorm.', parentNodeId: 'a1b2c3d4-e5f6-...', // Target folder UUID ); if (noteResult.ok && noteResult.item != null) { final note = noteResult.item!; print('Created: ${note.title}'); print('Preview: ${note.previewText}'); print('Tags: ${note.tags}'); } ``` -------------------------------- ### Rust Backend: Update Event Times Source: https://github.com/wyi1223/lazylife/blob/main/docs/releases/v0.1/prs/PR-0012-calendar-minimal.md Updates the start and end times for a given calendar event. It includes validation to ensure the end time is not before the start time, returning a specific validation error if the window is invalid. It also handles cases where the atom is not found. ```rust /// Updates the start and end times for a calendar event. /// Validates that `end_at >= start_at`. /// Returns `RepoError::Validation(InvalidEventWindow)` on failure. /// Returns `RepoError::NotFound` if no atom was changed (e.g., missing ID). pub fn update_event_times( &mut self, id: AtomId, start_at: i64, end_at: i64, ) -> Result<(), RepoError> { // ... implementation details ... Ok(()) // Placeholder } ``` -------------------------------- ### Today Section SQL Query Source: https://github.com/wyi1223/lazylife/blob/main/docs/architecture/data-model.md SQL query to retrieve items considered 'active today'. It includes DDL tasks due today or overdue, ongoing tasks started today, and events overlapping today. Excludes deleted and completed/cancelled tasks. Results are ordered by start or end time. ```sql WHERE is_deleted = 0 AND (task_status IS NULL OR task_status NOT IN ('done', 'cancelled')) AND ( -- DDL overdue or due today [NULL, Value] (end_at IS NOT NULL AND end_at <= :eod AND start_at IS NULL) -- Ongoing task already started [Value, NULL] OR (start_at IS NOT NULL AND end_at IS NULL AND start_at <= :eod) -- Event overlapping today [Value, Value] OR (start_at IS NOT NULL AND end_at IS NOT NULL AND start_at <= :eod AND end_at >= :bod) ) ORDER BY COALESCE(start_at, end_at) ASC, updated_at DESC ``` -------------------------------- ### Logging Initialization API (Rust FFI) Source: https://context7.com/wyi1223/lazylife/llms.txt Initializes Rust core logging with rolling file support. It is idempotent for the same configurations but rejects conflicting reconfigurations. Returns an empty string on success or an error message on failure. ```rust use flutter_rust_bridge::frb; #[frb(sync)] pub fn init_logging(level: String, log_dir: String) -> String { // Returns empty string on success, error message on failure // level: trace|debug|info|warn|error (case-insensitive) // log_dir: absolute path to log directory unimplemented!() } ``` -------------------------------- ### Breaking Changes Definition Source: https://github.com/wyi1223/lazylife/blob/main/docs/governance/API_COMPATIBILITY.md Defines what constitutes a breaking change in the API, including specific examples of actions that are considered breaking. ```APIDOC ## Breaking Changes A change is considered breaking when any of the following happens: - rename/remove an exposed FFI function - change parameter semantics, units, or requiredness - change return field semantics (including `ok/error_code` behavior) - remove or repurpose stable error codes - change Single Entry behavior boundary (`onChanged` vs `Enter/send`) - add new required (non-optional) request parameters without compatibility fallback ``` -------------------------------- ### Analyze Project Code (Shell) Source: https://github.com/wyi1223/lazylife/blob/main/docs/releases/v0.1/prs/PR-0010C3-note-autosave-switch-flush.md This command analyzes the Dart code within the `apps/lazynote_flutter` directory for potential issues and style guide violations. ```bash cd apps/lazynote_flutter && flutter analyze ```