taskflare
A Dart CLI tool that runs your dev commands, parses their output to determine a single unambiguous result, and notifies you when they're done. Currently wraps dart test / flutter test; designed to grow to other commands (lint, build, codegen, …) behind a single menu-driven entry point.
Outcomes
Every run ends with exactly one of three outcomes:
| Outcome | Meaning |
|---|---|
[SUCCESS] |
All tests passed |
[FAILURE] |
At least one test failed |
[CRASH] |
Tests did not run or the process crashed before completing |
Usage
Run it from the root of any Dart or Flutter project.
Interactive menu
dart run taskflare
Opens the main menu with options for Help, Config, and Run command. Designed for exploring taskflare for the first time.
Run tests directly
dart run taskflare test
dart run taskflare test --name "my test"
dart run taskflare test test/parser/
Help
dart run taskflare help # Interactive command list
dart run taskflare help test # Print test command help directly
Config
dart run taskflare config # Interactive configuration menu
Example output:
FAIL ▶ parses failure when done reports failure test/parser/json_event_parser_test.dart:42
THROW ▶ throws when input is malformed test/parser/json_event_parser_test.dart:91
SKIP ▶ skipped scenario
[FAILURE] passed: 108 failed: 2 skipped: 1 (14.3s)
FAIL— assertion error (expectfailed)THROW— uncaught exception thrown during the testSKIP— test was skipped- File references are printed as
path/to/file.dart:line— Ctrl+click in most terminals and IDEs to jump directly to the test
The progress line updates in-place while tests run and is erased when the run completes, leaving only the permanent failure/skip lines and the final summary.
Windows notifications
On Windows, taskflare sends a native desktop toast notification at the end of each run and an immediate toast when a test fails.
On first run, taskflare automatically:
- Writes the bundled app icon to
%LOCALAPPDATA%\Taskflare\taskflare.ico - Registers
Taskflare.AppinHKCU\Software\Classes\AppUserModelId\ - Creates a Start Menu shortcut (
Taskflare.lnk) with the AppUserModelID set
This is what makes the Taskflare icon appear next to the app name in the notification header. No manual setup required. Re-registration happens automatically if any of the three components is missing (e.g. after a clean install or manual deletion).
To replace the icon, overwrite %LOCALAPPDATA%\Taskflare\taskflare.ico with any ICO file, then delete the Start Menu shortcut so it is recreated on the next run:
Remove-Item "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Taskflare.lnk" -Force
Requirements
- Dart SDK
>=3.0.0 <4.0.0 - Windows toast notifications require Windows 10 or later
Architecture
taskflare follows a clean, layered architecture. Each layer has a single responsibility and depends only on the layers below it.
bin/
└── taskflare.dart Entry point — dispatches menu / help / config / commands
lib/src/
├── cli/ CLI entry points (menu-driven)
│ ├── profile/ CommandProfile base + concrete profiles (TestProfile, …)
│ ├── command_registry.dart Central list of runnable commands (drives menu/help/run)
│ ├── menu_command.dart Main menu shown by bare `taskflare`
│ ├── help_command.dart Interactive help + `help <name>` shortcut
│ ├── run_command.dart "Run command" submenu
│ ├── config_command.dart Interactive configuration menu
│ ├── test_command.dart Wires Taskflare for the `test` command
│ └── terminal.dart TerminalSession — owns the alt screen buffer, injected into all TUI screens
├── config/
│ └── taskflare_config.dart Persisted user preferences (filter + report toggles)
├── utils/ Shared utilities
│ ├── enums.dart TestResultKind and TestOutcome enums
│ └── project_detector.dart Detects Flutter vs. Dart project from pubspec.yaml
├── entities/ Immutable value objects (events, run_summary, …)
├── parser/
│ └── json_event_parser.dart Reads test JSON lines → produces a RunSummary
├── runner/ Abstract CommandRunner + process-based runners (dart / flutter test)
├── reporter/ Markdown run report writer (+ per-test records)
├── notifier/ Console + Windows toast notifiers, progress line, composite
└── taskflare.dart Orchestrator: runner → parser → notifier + reporter
lib/assets/
└── icon.png Bundled app icon (written to LocalAppData on first run)
Layer rules
utils ← no dependencies
entities ← utils
config ← no dependencies (pure persisted preferences)
parser ← entities, utils
runner ← utils
reporter ← entities, utils
notifier ← entities, utils
taskflare ← runner, parser, notifier, reporter, entities, utils (orchestrator only)
cli ← all layers (entry points that wire everything)
The orchestrator depends only on abstractions (CommandRunner, Notifier, ReportWriter) — never on concrete implementations. Swapping them requires no changes to taskflare.dart.
Extending taskflare
Add a new command (e.g. taskflare lint):
- Create
lib/src/cli/profile/lint_profile.dartextendingCommandProfile— implementname,description,helpText,commandLabel, andbuildRunner - Create
lib/src/cli/lint_command.dartwiringTaskflarefor the new profile (notifier, reporter, progress options) - Add an entry to
commandRegistryinlib/src/cli/command_registry.dart— menu, help, and run submenu pick it up automatically
Add a new runner (e.g. wrap dart run build_runner build):
- Create
lib/src/runner/build_runner_runner.dartextendingCommandRunner - Override
run()to launch the command and return aCommandResult - Add tests in
test/runner/build_runner_runner_test.dart - Pass it to
Taskflare(runner: BuildRunnerRunner(), ...)from a profile
Add a new notifier (e.g. webhook, Slack):
- Create
lib/src/notifier/slack_notifier.dartimplementingNotifier - Implement
notify(RunSummary summary) - Add tests in
test/notifier/slack_notifier_test.dart - Pass it to
Taskflare(notifier: SlackNotifier(), ...)
Running tests
dart test
The integration tests in test/runner/ spin up real subprocesses using the fixture projects under test/fixtures/. They take a few seconds — all other tests are pure unit tests and run instantly.
Project conventions
| Document | Contents |
|---|---|
doc/conventions_testing.md |
Test structure, group/test naming rules, what must be covered |
doc/conventions_architecture.md |
Folder layout, layer dependency rules, naming patterns |
doc/learnings.md |
Problems encountered and what we learned from them |
Libraries
- taskflare
- A Dart CLI tool that wraps
dart test(orflutter test), parses the JSON event stream, reports live progress in the terminal, and fires desktop notifications on test failure and completion.