Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,26 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.0] - 2025-07-10
## [1.2.0] - 2025-07-12

### Added

- **Session Targets**: Set a duration goal for your work session with `flow start --target 2h`. The `status` command will now display your progress and remaining time.
- **Daily Goals**: Set and track a daily focus goal with the new `flow goal` command. Use `flow goal --set 4h` to define your target and `flow goal` to view your progress.
- **Recent Sessions Summary**: Get a quick summary of today's completed sessions with the new `flow recent` command.
- **Productivity Insights**: Analyze your work patterns with the new `flow insights` command, which shows your busiest day, average session length, and more.
- **System Doctor**: Diagnose and troubleshoot your setup with the new `flow doctor` command to check for common configuration and data issues.

### Changed

- The `flow status` command now provides more detailed output for active sessions that have a target duration.
- The `flow pause` command output has been updated for better clarity.

### Fixed

- Corrected a test in the end-to-end suite that was failing due to updated command output, making the test suite more robust.

## [1.1.2] - 2025-07-10

### Added

Expand Down
165 changes: 88 additions & 77 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,144 +5,155 @@
[![Go Version](https://img.shields.io/github/go-mod/go-version/e6a5/flow)](https://go.dev/)
[![GitHub license](https://img.shields.io/github/license/e6a5/flow)](https://github.com/e6a5/flow/blob/main/LICENSE)

**Flow is a minimalist command-line tool for focused, single-tasking work sessions. It protects your attention, helps you build a deep work habit, and provides powerful insights into your focus patterns—all without leaving your terminal.**
**In a world of constant distraction, your attention is a superpower. Flow is a minimalist command-line tool that helps you protect it. It's for developers, writers, and anyone who wants to build a deep work habit without leaving the terminal.**

![Flow Dashboard](assets/dashboard.png)

It's designed for developers, writers, and anyone who wants to build a more mindful and effective relationship with their work.

---

## Table of Contents

- [The Philosophy](#the-philosophy-your-attention-is-sacred)
- [Features](#features)
- [Installation](#installation)
- [Getting Started](#getting-started-a-typical-workflow)
- [Commands](#full-command-reference)
- [Customization](#customization)
- [Contributing](#contributing)

---

## The Philosophy: Your Attention is Sacred

> In a world of constant distraction, your ability to focus is a superpower. Flow is built on a simple idea: **one thing at a time**. It's not about complex productivity metrics or chasing a never-ending task list. It's about creating a clear, intentional boundary around your work, allowing you to engage deeply and mindfully.
>
> Flow helps you answer a simple question: "What am I working on right now?" And by logging your completed sessions, it helps you reflect on a more important one: "How am I investing my attention?"
## The Flow Philosophy

## Features
Flow is built on a few core principles that guide its design and purpose.

- **Mindful Focus**: A single active session at a time to encourage deep, single-tasking work.
- **Rich Dashboard**: A beautiful, GitHub-style contribution graph to visualize your focus history over the last year.
- **Powerful Exports**: Export your work sessions to CSV or JSON for invoicing, analysis, or personal records.
- **Privacy First**: Your data is yours. Everything is stored locally in plain text files. No cloud, no tracking.
- **Shell Integration**: Seamlessly display your current focus session in your shell prompt (`bash` and `zsh` supported).
- **Automation Hooks**: Trigger custom scripts on session events (`on_start`, `on_pause`, `on_end`).
- **Configurable Watcher**: Customize the reminder timings for the `watch` command to fit your personal workflow.
* **Mindful Focus, Not Just Time Tracking.** Flow isn't about logging hours for a timesheet. It's about creating a ritual around deep work, helping you build the habit of single-tasking.

## Installation
* **Your Terminal is Your Sanctuary.** Deep work happens when you eliminate distractions. Flow lives in the command line, your most focused environment, preventing the context-switching required by GUI apps.

```bash
curl -sSL https://raw.githubusercontent.com/e6a5/flow/main/install.sh | bash
```
* **Your Data is Yours. Period.** Flow is private by default. It works offline, requires no account, and stores all your data in simple, local text files. You have complete control.

_The installer will add the `flow` binary to `/usr/local/bin` and check for necessary dependencies._
* **Compose Your Perfect Workflow.** Flow embraces the Unix philosophy. It's a simple, powerful tool that can be scripted and combined with others. Use its hooks to integrate with your existing setup.

For other installation methods (Go, manual), see the [Installation Guide](docs/INSTALL.md).
---

## Getting Started: A Typical Workflow
## A Typical Workflow

Flow is designed to be intuitive. Here's how a typical session works:

1. **Start a session** when you're ready to focus. Give it a tag to describe your task.
1. **Start a session** when you're ready to focus. Give it a tag and a target duration.

```bash
flow start --tag "Writing the first draft of the new feature spec"
flow start --tag "Writing the first draft" --target 2h
```

2. **Check your status** at any time.
2. **Check your status** at any time to see your progress.

```bash
flow status
> 🌊 Deep work: Writing the first draft of the new feature spec (Active for 1h 15m)
> 🌊 Deep work: Writing the first draft (Active for 45m) / 2h 0m (1h 15m remaining)
```

3. **Take a break** when you need one.
3. **End the session** when the work is complete. Your focus time is automatically logged.

```bash
flow pause
flow end
> ✨ Session complete: Writing the first draft
> Total focus time: 2h 5m
```

Then, **resume** when you're ready to get back to it.

4. **Review your day** and find your patterns.
```bash
flow resume
flow recent
flow insights
```
---

4. **End the session** when the work is complete. Your focus time is automatically logged.
## Installation

```bash
flow end
> ✨ Session complete: Writing the first draft of the new feature spec
> Total focus time: 2h 30m
```
```bash
curl -sSL https://raw.githubusercontent.com/e6a5/flow/main/install.sh | bash
```

5. **(Optional) Use the Watcher** to get gentle reminders. Run this in a separate, dedicated terminal tab.
```bash
flow watch
```
_The installer will add the `flow` binary to `/usr/local/bin` and check for necessary dependencies._

For other installation methods (Go, manual), see the [Installation Guide](docs/INSTALL.md).

## Table of Contents

- [Goals and Insights: Understand Your Work](#goals-and-insights-understand-your-work)
- [Full Command Reference](#full-command-reference)
- [Customization](#customization)
- [Contributing](#contributing)

---

## Gain Insights from Your Work
## Goals and Insights: Understand Your Work

Once you've logged a few sessions, you can use Flow's data tools to understand your work patterns.
Flow is more than a timer; it's a tool for building habits. Once you've logged a few sessions, you can use its data tools to understand and improve your work patterns.

- **Visualize your consistency** with the dashboard. The color of each day represents your total focus time:
- **Set a daily goal** to build consistency:
```bash
flow goal --set 4h
```
Check your progress at any time:
```bash
flow goal
> 🎯 Daily Goal: 2h 5m / 4h 0m (52%)
```

- **Lightest Blue**: 1 minute - 2 hours
- **Light Blue**: 2 - 4 hours
- **Medium Blue**: 4 - 6 hours
- **Darkest Blue**: More than 6 hours
- **Review today's progress** with the `recent` command:
```bash
flow recent
> ✨ Today's Completed Sessions ✨
>
> - Writing the first draft (2h 5m)
>
> Total focus time today: 2h 5m
```

- **Discover your patterns** with `insights`:
```bash
flow dashboard
flow insights
> 📊 Your Focus Insights (based on 42 sessions)
> ----------------------------------------------------
> Busiest Day: Thursday
> - You focus an average of 2h 15m on Thursdays.
> - Your average on other days is 1h 10m.
>
> Top Activities (by time):
> - coding: 18h 5m (51%)
> - writing: 9h 45m (28%)
> ----------------------------------------------------
```

- **Review your session history**:
- **Visualize your consistency** with the dashboard:
```bash
flow log --week --stats
flow dashboard
```

- **Export your data for invoicing or analysis**:
```bash
flow export --month 2023-10 --format csv --output "october-invoice.csv"
flow export --month 2023-10 --format csv
```

## Full Command Reference

### Core Session Commands

| Command | Description |
| ---------------------- | ---------------------------------------------- |
| `start [--tag "name"]` | Begin a deep work session. |
| `status [--raw]` | Check the current session status. |
| `pause` | Pause the active session. |
| `resume` | Resume a paused session. |
| `end` | Complete the session and log it. |
| `watch` | Run a watcher to get gentle, timely reminders. |
| Command | Description |
| --------------------------- | ---------------------------------------------- |
| `start [--tag ""][--target ""]` | Begin a deep work session with an optional target duration. |
| `status [--raw]` | Check the current session status. |
| `pause` | Pause the active session. |
| `resume` | Resume a paused session. |
| `end` | Complete the session and log it. |
| `watch` | Run a watcher to get gentle, timely reminders. |

### Data & Analysis Commands

| Command | Description |
| ---------------- | ----------------------------------------------------------------------- |
| `log [flags]` | View completed session history. See `flow log --help` for flags. |
| `recent` | Show a summary of today's completed sessions. |
| `dashboard` | Show a yearly contribution graph of your focus sessions. |
| `insights` | Analyze your work history to see patterns like your busiest day. |
| `export [flags]` | Export session data to CSV or JSON. See `flow export --help` for flags. |

### Utility Commands

| Command | Description |
| ------------------------ | ---------------------------------- |
| `completion [bash\|zsh]` | Generate shell completion scripts. |
| Command | Description |
| ------------------------ | ------------------------------------------------------ |
| `goal [--set ""]` | Set or view your daily focus goal. |
| `doctor` | Run a diagnostic check on your Flow setup. |
| `completion [bash\|zsh]` | Generate shell completion scripts. |

## Customization

Expand Down
90 changes: 90 additions & 0 deletions cmd/doctor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package cmd

import (
"fmt"
"os"

"github.com/e6a5/flow/core"
"github.com/spf13/cobra"
)

var doctorCmd = &cobra.Command{
Use: "doctor",
Short: "Run a diagnostic check on your Flow setup",
Long: `Checks for common problems with your configuration, session files, and log data.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("🩺 Running diagnostics...")
allGood := true

// Check 1: Config file
cfgPath, err := core.GetConfigPath()
if err != nil {
fmt.Println("❌ Config Path: Could not determine config path.")
allGood = false
} else {
_, err := os.Stat(cfgPath)
if os.IsNotExist(err) {
fmt.Printf("✅ Config File: OK (No config file found, using defaults).\n")
} else if err != nil {
fmt.Printf("❌ Config File: Error checking config at %s: %v\n", cfgPath, err)
allGood = false
} else {
// Try to load it
_, err := core.LoadConfig()
if err != nil {
fmt.Printf("❌ Config File: Found at %s, but could not parse: %v\n", cfgPath, err)
allGood = false
} else {
fmt.Printf("✅ Config File: OK (Loaded successfully from %s).\n", cfgPath)
}
}
}

// Check 2: Session file
sessionPath, err := core.GetSessionPath()
if err != nil {
fmt.Println("❌ Session Path: Could not determine session path.")
allGood = false
} else {
if core.SessionExists() {
_, err := core.LoadSession()
if err != nil {
fmt.Printf("❌ Session File: Corrupted or unreadable at %s: %v\n", sessionPath, err)
allGood = false
} else {
fmt.Printf("✅ Session File: OK (Readable at %s).\n", sessionPath)
}
} else {
fmt.Printf("✅ Session File: OK (No active session).\n")
}
}

// Check 3: Log directory
logDir, err := core.GetLogDir()
if err != nil {
fmt.Println("❌ Log Directory: Could not determine log directory.")
allGood = false
} else {
info, err := os.Stat(logDir)
if os.IsNotExist(err) {
fmt.Printf("✅ Log Directory: OK (Will be created at %s).\n", logDir)
} else if err != nil || !info.IsDir() {
fmt.Printf("❌ Log Directory: Path at %s is not a valid directory.\n", logDir)
allGood = false
} else {
fmt.Printf("✅ Log Directory: OK (Exists at %s).\n", logDir)
}
}

fmt.Println()
if allGood {
fmt.Println("✨ Your Flow setup looks healthy! ✨")
} else {
fmt.Println("⚠️ Found issues with your setup. Please review the messages above.")
}
},
}

func init() {
rootCmd.AddCommand(doctorCmd)
}
Loading
Loading