https://github.com/sparshsam/openjournal
Privacy-first local activity journal for Windows
https://github.com/sparshsam/openjournal
activity-tracker journaling local-first privacy productivity react rust sqlite tauri windows
Last synced: about 7 hours ago
JSON representation
Privacy-first local activity journal for Windows
- Host: GitHub
- URL: https://github.com/sparshsam/openjournal
- Owner: sparshsam
- License: other
- Created: 2026-06-15T16:40:46.000Z (14 days ago)
- Default Branch: master
- Last Pushed: 2026-06-15T19:50:42.000Z (14 days ago)
- Last Synced: 2026-06-15T21:22:35.052Z (14 days ago)
- Topics: activity-tracker, journaling, local-first, privacy, productivity, react, rust, sqlite, tauri, windows
- Language: Rust
- Homepage: https://github.com/sparshsam/openjournal
- Size: 161 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
- Support: SUPPORT.md
- Roadmap: ROADMAP.md
Awesome Lists containing this project
README
# OpenJournal
**Privacy-first local activity journal for Windows.**
[](./LICENSE)
[]()
[]()
[]()
[]()
[](CONTRIBUTING.md)

---
## Features
- **Automatic activity tracking** — Records focused app names, window titles, and duration locally
- **System tray integration** — Show window, pause/resume logging, or quit from the tray icon
- **Daily timeline** — Browse your day's focused windows with start/end times and durations
- **Private blocklist** — Skip sensitive apps, domains, or title patterns before anything is stored
- **Pause/resume logging** — One-click pause from the app or system tray
- **Markdown & JSON export** — Export your day's activity as a formatted timeline or structured data
- **Delete day** — Remove all activity for a selected day
- **Privacy-first from the ground up** — No cloud, no telemetry, no data leaving your device
## Privacy-First Principles
OpenJournal is built on a simple promise: **everything stays on your device.**
### What OpenJournal records
- The **name** of the focused application (e.g., `Code.exe`, `WindowsTerminal.exe`)
- The **title** of the focused window (e.g., "OpenJournal - lib.rs")
- When focus **started** and **ended**
- The calculated **duration** of each focus session
### What OpenJournal does NOT collect
| Feature | Status |
|---------|--------|
| Keystrokes | ❌ Never recorded |
| Clipboard contents | ❌ Never read |
| Passwords or typed text | ❌ Never recorded |
| Screenshots or screen recordings | ❌ Never captured |
| Microphone input | ❌ Never accessed |
| Camera input | ❌ Never accessed |
| Cloud data / network sync | ❌ Never sent |
| Telemetry or analytics | ❌ Never collected |
| External API calls | ❌ None in v0.1 (opt-in only in future versions) |
| Keylogging of any kind | ❌ Explicitly prevented |
### Data storage
All data is stored in a local SQLite database under the Tauri app data directory:
```
%APPDATA%\dev.openjournal.app\openjournal.sqlite3
```
## Installation
### Download
Download the latest installer from the [Releases page](https://github.com/sparshsam/openjournal/releases).
1. Download `OpenJournal_v0.1.3_x64-setup.exe`
2. Run the installer
3. Launch OpenJournal from the Start menu
### Build from source
```powershell
# Prerequisites
# - Windows 10 or Windows 11
# - Node.js 22+
# - Rust 1.96+ and Cargo
# - Visual Studio C++ build tools
# - WebView2 (included in Windows 10+)
git clone https://github.com/sparshsam/openjournal.git
cd openjournal
npm install
npm run tauri:build
```
## How Activity Tracking Works
OpenJournal uses the Windows Win32 API to monitor the foreground window.
1. Every **5 seconds**, OpenJournal calls `GetForegroundWindow()` to find the active window
2. It retrieves the **window title** via `GetWindowTextW()` and the **process image name** via `QueryFullProcessImageNameW()`
3. If the window or app matches a blocklist pattern, the activity is **discarded before storage**
4. If logging is **paused**, the current session is flushed and no new entries are created
5. If the window **changes**, the previous session is closed and a new one starts
6. Durations are calculated as `ended_at - started_at` and stored in seconds
No data is ever sent over the network.
## Export Examples
### Markdown
```markdown
| Start | End | Duration | App | Window |
| --- | --- | ---: | --- | --- |
| 2026-06-15T09:00:00Z | 2026-06-15T09:39:00Z | 2340s | Code.exe | openjournal - lib.rs |
| 2026-06-15T09:42:00Z | 2026-06-15T09:57:00Z | 900s | msedge.exe | Tauri system tray docs |
```
### JSON
```json
{
"day": "2026-06-15",
"activities": [
{
"id": 1,
"app_name": "Code.exe",
"window_title": "openjournal - lib.rs",
"started_at": "2026-06-15T09:00:00Z",
"ended_at": "2026-06-15T09:39:00Z",
"duration_seconds": 2340
}
],
"summaries": []
}
```
## Data Model
| Table | Description |
|-------|-------------|
| `activity_entries` | Focused app/window sessions with start, end, and duration |
| `blocklist_entries` | Private app, domain, and title patterns to skip before storage |
| `settings` | Local app settings (e.g., paused logging state) |
| `summary_blocks` | Reserved for v0.2 generated AI summaries |
## Development
```powershell
# Install dependencies
npm install
# Run the web dev server (browser preview)
npm run dev
# Build the frontend
npm run build
# Run Tauri dev (desktop app with hot-reload)
npm run tauri:dev
# Build release installer
npm run tauri:build
# Rust quality checks
cd src-tauri
cargo fmt -- --check
cargo check
cargo clippy --all-targets
cargo test
```
## AI Summaries (v0.2)
OpenJournal v0.2 introduces optional AI-powered 3-hour summaries. AI is **disabled by default** — no data is sent anywhere unless you explicitly enable it.
### Supported Providers
| Provider | Type | Default | Status |
|----------|------|---------|--------|
| **LM Studio** | Local (HTTP) | `http://localhost:1234/v1` | ✅ Implemented |
| **Ollama** | Local (HTTP) | `http://localhost:11434` | ✅ Implemented |
| **OpenAI-compatible** | Remote (opt-in) | — | Scaffolded, disabled by default |
### How It Works
1. Activity is aggregated into **8 x 3-hour blocks** per day
2. Each block's data (app names, durations, context switches) is combined into a structured prompt
3. The prompt is sent to your configured local provider
4. The AI returns a structured JSON summary (main focus, apps, context switches, notes, plain-English summary)
5. The summary is stored locally in SQLite
### Privacy
- ✅ **AI is off by default.** OpenJournal works exactly as before when no provider is configured.
- ✅ **LM Studio and Ollama run locally.** No data leaves your machine.
- ✅ **External providers are opt-in.** You must explicitly enable and configure them.
- ✅ **No telemetry.** OpenJournal never sends usage data.
- ✅ **All prompts are generated from local data only.** App names, window titles, and durations — no keystrokes, clipboard, or passwords.
### Setup
1. Install [LM Studio](https://lmstudio.ai/) or [Ollama](https://ollama.com/)
2. Load a model (e.g., `llama3.2` for Ollama, or any model in LM Studio)
3. In OpenJournal, go to **AI Settings**
4. Enable AI, select your provider, and enter the base URL
5. Click **Test Connection** to verify
6. Click **Generate Summary** on any 3-hour block
### DeepSeek Setup (Default)
OpenJournal ships with DeepSeek as the default AI provider. To use it:
1. Get an API key from [platform.deepseek.com](https://platform.deepseek.com/)
2. Set it as an environment variable:
```bash
# PowerShell
$env:OPENJOURNAL_DEEPSEEK_API_KEY = "sk-your-key-here"
# CMD
set OPENJOURNAL_DEEPSEEK_API_KEY=sk-your-key-here
```
Or use the standard `DEEPSEEK_API_KEY` variable.
3. Restart OpenJournal
4. Go to **AI Settings** and enable AI
5. The "Using env:" indicator should show a masked key
6. Click **Test Connection** to verify
### Provider Endpoints
| Provider | Default URL | API Format |
|----------|-------------|------------|
| LM Studio | `http://localhost:1234/v1` | OpenAI-compatible `/v1/chat/completions` |
| Ollama | `http://localhost:11434` | Ollama `/api/chat` |
See [ROADMAP.md](./ROADMAP.md) for the full plan.
## Ecosystem Role
OpenJournal is part of the [sparshsam ecosystem](https://github.com/sparshsam) of privacy-first, local-first tools. It fills the niche of lightweight, automatic activity tracking without cloud dependencies — complementing other tools like [chess-by-sparsh](https://github.com/sparshsam/chess-by-sparsh) and [openscrabble](https://github.com/sparshsam/openscrabble) by providing a private infrastructure layer for personal time awareness.
## Architecture
See [ARCHITECTURE.md](./ARCHITECTURE.md) for the system design — including the Windows Win32 polling loop, SQLite storage layer, export pipeline, and AI summary provider pattern.
## Roadmap
See [ROADMAP.md](./ROADMAP.md) for the full versioned plan.
## Limitations
- **Windows only.** OpenJournal uses Win32 API calls (`GetForegroundWindow`, `GetWindowTextW`) and will not work on macOS or Linux.
- **No timeline corrections.** Duration is recorded per—focus session. Manual time adjustments are not supported.
- **No persistent filtering.** Blocklisted apps prevent recording, but past data cannot be retroactively filtered.
- **No multi-window tracking.** Only the foreground window is recorded. Background windows are not tracked.
- **No network features.** This is a local-only tool. There is no sync, no cloud backup, and no remote access.
- **AI summaries are opt-in and experimental.** v0.2 introduces local AI summarization; accuracy depends on the model and provider you choose.
- **Not a security audit tool.** OpenJournal records app and window titles you can already see. It does not detect malware, keyloggers, or unauthorized access.
## License
AGPL-3.0-or-later. See [LICENSE](./LICENSE).
## Contributing
See [CONTRIBUTING.md](./CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md).