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
38 changes: 38 additions & 0 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# .github/release-drafter.yml

# Configuration for Release Drafter: https://github.com/release-drafter/release-drafter

# Name of the next release.
# The '$NEXT_PATCH_VERSION' variable will be automatically replaced with the next patch version number (e.g., v1.2.1).
# You can also use '$NEXT_MINOR_VERSION' or '$NEXT_MAJOR_VERSION'.
name-template: "v$NEXT_PATCH_VERSION"
tag-template: "v$NEXT_PATCH_VERSION"

# Categories for changes. These are matched against the labels on your Pull Requests.
categories:
- title: "🚀 New Features"
labels:
- "feature"
- "enhancement"
- title: "🐛 Bug Fixes"
labels:
- "fix"
- "bug"
- title: "📚 Documentation"
labels:
- "docs"
- "documentation"
- title: "🧹 Maintenance"
labels:
- "chore"
- "refactor"
- "ci"

# Template for the release notes body.
# '$CHANGES' will be replaced with the categorized list of Pull Requests.
template: |
## What's Changed

$CHANGES

**Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$NEXT_PATCH_VERSION
22 changes: 22 additions & 0 deletions .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# .github/workflows/release-drafter.yml
name: Release Drafter

on:
push:
# We only want this to run on pushes to the main branch.
branches:
- main

jobs:
update_release_draft:
runs-on: ubuntu-latest
steps:
# Drafts the next release by adding new changes from merged pull requests.
- uses: release-drafter/release-drafter@v6
with:
# You can find the config file in .github/release-drafter.yml
config-name: release-drafter.yml
env:
# This token is provided by GitHub Actions.
# It's required for the action to create and update the draft release.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23 changes: 22 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,25 @@ 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

### Added

- **Watcher**: A new `flow watch` command that runs as a long-running process to provide gentle, timely reminders to start, pause, resume, or end a focus session. This is an opt-in feature designed to help users who forget to interact with the timer.
- **Watcher Configuration**: The watcher's reminder timings can be customized via a new `~/.config/flow/config.yml` file. See the [Customization Guide](docs/CUSTOMIZATION.md) for details.

### Changed

- **Dependency**: Migrated from the archived `gopkg.in/yaml.v3` to the actively maintained `github.com/goccy/go-yaml` for improved security and reliability.

### Fixed

- Addressed a potential supply chain vulnerability by replacing an archived dependency.

## [Unreleased]

### Added

- Initial release of Flow
- Focus timer with countdown display
- Task tagging with `--tag` flag
Expand All @@ -22,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Automatic creation of installation directory if it doesn't exist

### Changed

- Upgraded to Go 1.23.0
- Removed direct Zenta integration in favor of Unix composition

Expand All @@ -32,25 +49,29 @@ Flow follows semantic versioning and Unix philosophy. Breaking changes will only
## [0.1.0] - 2025-07-01

### Added

- **Session Logging**: Automatic tracking of completed sessions with the `flow log` command.
- **Partitioned Log Files**: Logs are now stored in `YYYYMM_sessions.jsonl` files for improved performance and scalability.
- **Log Filtering**: Filter logs by `--today`, `--week`, `--month`, or a specific month (`YYYY-MM`).
- **Log Statistics**: View summary statistics with `flow log --stats`.
- **Shell Completions**: Added completions for the `log` command and its flags.

### Changed

- **Messaging**: Updated the `flow start` message to be more accurate ("Deep work session initiated").
- **Code Quality**: Fixed all `errcheck` linting issues for improved reliability.
- **Build Process**: Added a `lint` command to the `Makefile`.

### Fixed

- **Error Handling**: Improved error handling for file operations.

## [0.0.2] - 2024-06-15

### Added

- Initial release of Flow
- Session management: `start`, `pause`, `resume`, `end`
- XDG-compliant storage at `~/.local/share/flow/session`
- Automation hooks for workflow integration
- Single-session enforcement for focus
- Single-session enforcement for focus
27 changes: 21 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,26 @@ We use GitHub to host code, to track issues and feature requests, as well as acc

### Pull Requests

1. Fork the repo and create your branch from `main`
2. If you've added code that should be tested, add tests
3. Ensure the test suite passes with `make test`
4. Make sure your code is formatted with `make fmt`
5. Issue that pull request!
We actively welcome your pull requests.

1. Fork the repo and create your branch from `main`.
2. If you've added code that should be tested, add tests.
3. Ensure the test suite passes with `make test`.
4. Make sure your code is formatted with `make fmt`.
5. Title your Pull Request using the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format. This helps us automate our release notes. For example:
- `feat: Add a new command for exporting data`
- `fix: Correctly handle paused session state`
- `docs: Update the README with new instructions`
6. Add a label to your Pull Request that matches the type of change. This is used to categorize the change in our release notes. The available labels are:
- `feature` / `enhancement`
- `bug` / `fix`
- `documentation` / `docs`
- `chore` / `refactor` / `ci`
7. Issue that pull request!

### Release Process (for maintainers)

This project uses `release-drafter` to automate the creation of release notes.

### Development Setup

Expand Down Expand Up @@ -81,4 +96,4 @@ By contributing, you agree that your contributions will be licensed under its MI

## Questions?

Feel free to open an issue with the `question` label if you have any questions about contributing.
Feel free to open an issue with the `question` label if you have any questions about contributing.
50 changes: 35 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ It's designed for developers, writers, and anyone who wants to build a more mind
- **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.

## Installation

```bash
curl -sSL https://raw.githubusercontent.com/e6a5/flow/main/install.sh | bash
```
*The installer will add the `flow` binary to `/usr/local/bin` and check for necessary dependencies.*

_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).

Expand All @@ -54,41 +56,54 @@ For other installation methods (Go, manual), see the [Installation Guide](docs/I
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.

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

2. **Check your status** at any time.

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

3. **Take a break** when you need one.

```bash
flow pause
```

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

```bash
flow resume
```

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

```bash
flow end
> ✨ Session complete: Writing the first draft of the new feature spec
> Total focus time: 2h 30m
```

5. **(Optional) Use the Watcher** to get gentle reminders. Run this in a separate, dedicated terminal tab.
```bash
flow watch
```

## Gain Insights from Your Work

Once you've logged a few sessions, you can use Flow's data tools to understand your work patterns.

- **Visualize your consistency** with the dashboard. The color of each day represents your total focus time:

- **Lightest Blue**: 1 minute - 2 hours
- **Light Blue**: 2 - 4 hours
- **Medium Blue**: 4 - 6 hours
- **Darkest Blue**: More than 6 hours

```bash
flow dashboard
```
Expand All @@ -105,31 +120,36 @@ Once you've logged a few sessions, you can use Flow's data tools to understand y
## 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. |

| 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. |

### Data & Analysis Commands
| Command | Description |
| ------- | ----------- |
| `log [flags]` | View completed session history. See `flow log --help` for flags. |
| `dashboard` | Show a yearly contribution graph of your focus sessions. |

| Command | Description |
| ---------------- | ----------------------------------------------------------------------- |
| `log [flags]` | View completed session history. See `flow log --help` for flags. |
| `dashboard` | Show a yearly contribution graph of your focus sessions. |
| `export [flags]` | Export session data to CSV or JSON. See `flow export --help` for flags. |

### Utility Commands
| Command | Description |
| ------- | ----------- |

| Command | Description |
| ------------------------ | ---------------------------------- |
| `completion [bash\|zsh]` | Generate shell completion scripts. |

## Customization

You can extend Flow to fit your unique workflow using hooks and environment variables.

- **Automation Hooks**: Trigger custom scripts on session events.
- **Watcher Timings**: Customize reminder intervals for the `watch` command.
- **Configuration**: Customize storage paths using environment variables.

For detailed information, see the [Customization Guide](docs/CUSTOMIZATION.md).
Expand All @@ -144,4 +164,4 @@ Flow is open-source software licensed under the [MIT License](LICENSE).

---

*One thing at a time. Runs offline. Powered by presence.*
_One thing at a time. Runs offline. Powered by presence._
50 changes: 50 additions & 0 deletions cmd/watch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package cmd

import (
"fmt"
"os"
"time"

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

var watchCmd = &cobra.Command{
Use: "watch",
Short: "Watch the current session and provide gentle reminders",
Long: `Runs in the foreground and periodically checks the session status.
It provides gentle, timestamped nudges to help you remember to start,
pause, resume, or end a session. Designed to be run in a separate,
dedicated terminal tab.`,
Run: func(cmd *cobra.Command, args []string) {
cfg, err := core.LoadConfig()
if err != nil {
// If config fails to load, print a warning but continue with defaults.
fmt.Fprintf(os.Stderr, "Warning: could not load config file: %v\n", err)
}

fmt.Printf("[%s] 🌊 Flow Watcher started. Checking every %s.\n", time.Now().Format("03:04 PM"), cfg.Watch.Interval)

runOnce, _ := cmd.Flags().GetBool("_test_run_once")

watcher := core.NewWatcher()
for {
watcher.CheckSessionAndNudge(cfg)

if runOnce {
break
}
time.Sleep(cfg.Watch.Interval)
}
},
}

func init() {
rootCmd.AddCommand(watchCmd)
watchCmd.Flags().Bool("_test_run_once", false, "Run the watch loop only once for testing.")
if err := watchCmd.Flags().MarkHidden("_test_run_once"); err != nil {
// This is a developer error, not a user error.
// If we can't hide a flag we just defined, something is fundamentally wrong.
panic(err)
}
}
Loading
Loading