pour-design-spec

Project Pour — Design Specification (v0.2)

1. Product Overview

Pour is a blazing-fast, terminal-native (TUI) capture tool designed to eliminate the friction of logging structured data into Obsidian. Built in Rust (using ratatui), it acts as a headless data-entry client, allowing users to rapidly "pour" thoughts and coffee logs directly into their vault without breaking their CLI workflow.

Core Philosophy:

  • Offline-First Resilience: Works with the Obsidian Local REST API, but falls back seamlessly to direct file-system operations if the vault is closed.
  • Snappy & Rhythmic: Designed around the pour command. Fast muscle memory.
  • Data Integrity: Generates strict YAML frontmatter and standard Markdown to ensure 100% compatibility with Obsidian Properties (Bases) and Dataview.

2. User Experience & Command Routing

The application has two primary execution paths:

2.1 The Dashboard (pour)

Running the base command opens the main interactive hub.

  • Header: Displays vault connection status (🟢 API Connected | 🟡 Direct File Mode).
  • Body: Shows a summary of today's stats (e.g., "Poured today: 2 Coffees, 1 Journal").
  • Menu: Navigable list to launch specific modules (me, coffee).

2.2 The Fast Path (pour <module>)

Bypasses the dashboard and launches directly into a specific data-entry view.

  • pour me — Opens the journal appending view.
  • pour coffee — Opens the coffee logging form.

2.3 Post-Execution Summary

Upon submitting a form, the app does not immediately exit. It transitions to a Summary View displaying:

  • A success message with the destination file path.
  • Options: [Enter] Main Menu, [A] Pour Another → .., [Q] Quit, [O] Open file in $EDITOR.

3. Architecture & Data Layer

3.1 Hybrid Transport Layer

Pour uses a dual-pronged approach to writing data:

  1. Primary (API): Attempts a fast local HTTP request via reqwest to the Obsidian Local REST API (http://127.0.0.1:27124).
  2. Fallback (File System): If the connection is refused, it gracefully falls back to std::fs to write directly to the absolute vault path defined in the configuration.

API Authentication: The REST API plugin requires a Bearer token. Pour supports two sources:

  • api_key field under [vault] in config.toml.
  • POUR_API_KEY environment variable (takes precedence over config if set).

3.2 Dynamic Data Fetching & Caching

3-tier fallback (API → disk scan → cache → freetext) with async background refresh.

3.3 File Write Modes & Field → Output Mapping

Append vs. create modes, and how fields map to frontmatter/body.

4. Configuration, Field Types & Validation

Full TOML schema, field type reference, and validation rules — see config schema section.

6. Technical Stack

  • Language: Rust (2024 Edition)
  • TUI Framework: ratatui + crossterm
  • Serialization: serde, serde_json, toml, serde_yaml
  • Network: reqwest (with tokio for async fetching)
  • Time: chrono (for file formatting and timestamps)

7. Scope — v0.1

The following are explicitly in scope for v0.1:

  • Dashboard with connection status and module menu
  • pour me (append mode with Templater integration + atomic note fallback)
  • pour coffee (create mode with frontmatter generation)
  • Hybrid transport layer (API → filesystem fallback)
  • Dynamic data fetching (API → disk scan → cache → freetext)
  • Configurable append templates (callout default)
  • Configurable theme (accent color, border style)
  • Post-execution summary view
  • required field validation

The following are explicitly deferred:

  • pour music module (generic config supports it when ready)
  • Rich validation (min/max, regex)
  • Tag-based dynamic_select sources
  • Plugin/extension system