β Time, executed well.
β‘ Kairo is a keyboard-first, offline-first terminal task manager designed for focused execution. Built with Bubble Tea, Lip Gloss, and SQLite.
- Task Engine: Title, description (Markdown), tags, priority, deadline, status.
- Views: Inbox, Today, Upcoming, Tag, Priority.
- Command Palette: Ranked fuzzy search for tasks, commands, and tags.
- Offline Storage: SQLite with WAL + migrations for reliability and speed.
- Git Sync: Repo-backed, per-task JSON files, auto-commit, pull/push.
- Plugins: Lua-based commands and views with hot-reload.
- Import/Export: Support for JSON and Markdown.
- Theming: Built-in and user-definable theme overrides with runtime switching.
| Task Description | Help Menu | Theme Menu |
|---|---|---|
![]() |
![]() |
![]() |
Kairo is built with a modular architecture designed for performance, extensibility, and data sovereignty.
- UI Layer (Bubble Tea): An Elm-inspired functional TUI framework. Kairo uses a state-machine approach to manage different modes (List, Detail, Editor, Palette) and sub-component communication.
- Storage Layer (SQLite): A robust local database using
modernc.org/sqlite(pure Go). It features WAL (Write-Ahead Logging) for concurrent access and a migration system for schema evolution. - Sync Engine (Git): A unique "no-backend" synchronization strategy. It serializes tasks into individual JSON files within a local Git repository, leveraging Git's branching and merging capabilities for conflict resolution and versioning.
- Search Engine: An in-memory index utilizing a ranked fuzzy matching algorithm. It provides sub-millisecond search results by weighting matches based on contiguity and word boundaries.
- Plugin System (Gopher-Lua): A lightweight Lua VM integration. It allows users to extend the TUI with custom commands and views without recompiling the binary.
- Interaction: User input is captured by the Bubble Tea loop and dispatched to the active component.
- Persistence: Changes are immediately persisted to the SQLite database.
- Synchronization: If enabled, the Sync Engine periodically (or on-demand) exports database state to the Git-backed task files and performs
git pull/pushoperations. - Extensibility: Lua plugins can hook into the task creation/deletion lifecycle and inject new items into the command palette.
kairo/
βββ CHANGELOG.md
βββ cmd
β βββ kairo
β βββ main.go
βββ CODE_OF_CONDUCT.md
βββ configs
β βββ kairo.example.toml
βββ CONTRIBUTING.md
βββ go.mod
βββ go.sum
βββ internal
β βββ app
β β βββ model.go
β β βββ msg.go
β βββ config
β β βββ config.go
β β βββ config_test.go
β βββ core
β β βββ codec
β β β βββ json.go
β β β βββ markdown.go
β β βββ core_test.go
β β βββ ids.go
β β βββ nlp
β β β βββ deadline.go
β β βββ task.go
β β βββ view.go
β βββ plugins
β β βββ host.go
β βββ search
β β βββ fuzzy.go
β β βββ fuzzy_test.go
β β βββ index.go
β βββ storage
β β βββ migrations.go
β β βββ repo.go
β β βββ repo_test.go
β βββ sync
β β βββ engine.go
β βββ ui
β β βββ detail
β β β βββ model.go
β β βββ editor
β β β βββ model.go
β β βββ help
β β β βββ model.go
β β βββ keymap
β β β βββ keymap.go
β β β βββ keymap_test.go
β β β βββ normalize.go
β β β βββ normalize_test.go
β β βββ palette
β β β βββ model.go
β β βββ plugin_menu
β β β βββ model.go
β β βββ styles
β β β βββ styles.go
β β βββ tasklist
β β β βββ model.go
β β βββ theme
β β β βββ theme.go
β β βββ theme_menu
β β βββ model.go
β βββ util
β βββ paths.go
β βββ util_test.go
βββ LICENSE
βββ Makefile
βββ plugins
β βββ sample.lua
βββ README.md
βββ screenshots
β βββ app.png
β βββ help_menu.png
β βββ task_desc.png
β βββ theme_menu.png
βββ SECURITY.md
βββ VERSION.txt- Go 1.26+
git clone https://github.com/programmersd21/kairo.git
cd kairo
make buildFor a static binary (pure Go SQLite driver, no CGO):
CGO_ENABLED=0 make buildRun the binary:
./kairoKairo is designed for keyboard efficiency. All keybindings are configurable in your config.toml.
| Key | Action |
|---|---|
ctrl+p |
Open Command Palette (fuzzy search tasks, tags, and commands) |
/ |
Search tasks (fuzzy by name) |
tab |
Cycle to next view (Inbox β Today β Upcoming β ...) |
shift+tab |
Cycle to previous view |
t |
Open Theme Menu / Cycle themes |
ctrl+g |
Open Lua plugins folder |
p |
Manage plugins (list & uninstall) |
g |
Reload all Lua plugins |
| ? | Show Help overlay |
| q | Quit Kairo |
| Key | Action |
|---|---|
k / up |
Move selection up |
j / down |
Move selection down |
g / home |
Jump to top of list |
G / end |
Jump to bottom of list |
pgup / pgdown |
Scroll page up/down |
n |
Create a new task |
e |
Edit selected task |
d |
Delete selected task (requires confirmation) |
enter |
View detailed task information & Markdown description |
| Key | View |
|---|---|
1 |
Inbox: All active tasks |
2 |
Today: Tasks due today or overdue |
3 |
Upcoming: Tasks with future deadlines |
4 |
Tag: Filter tasks by a specific tag |
5 |
Priority: Filter tasks by priority level (P0-P3) |
| Key | Action |
|---|---|
ctrl+s |
Save changes (in Editor) |
tab |
Move to next input field |
shift+tab |
Move to previous input field |
esc |
Cancel / Go back to list |
Pro Tip: In the Command Palette (
ctrl+p), you can type commands likepri:0to jump to Priority 0 tasks, or#workto jump to a specific tag.
Copy the example configuration to your configuration directory:
- Windows:
%APPDATA%\kairo\config.toml - macOS:
~/Library/Application Support/kairo/config.toml - Linux:
~/.config/kairo/config.toml
Example:
cp configs/kairo.example.toml ~/.config/kairo/config.tomlEnable sync in your config.toml and set sync.repo_path to a local git repository.
Kairo uses a distributed approach:
- Each task is stored as an individual JSON file.
- Changes are committed locally automatically.
- Manual sync:
kairo sync
Kairo's plugin system allows you to extend the TUI with custom logic, views, and commands. Place .lua files in your plugins directory (e.g., ~/.config/kairo/plugins/).
Every plugin must return a table containing its metadata and optional commands and views.
| Field | Type | Description |
|---|---|---|
id |
string |
Unique identifier (defaults to filename) |
name |
string |
Display name in Plugin Manager |
description |
string |
Short summary of plugin features |
author |
string |
Plugin author name |
version |
string |
Current version (e.g., "1.0.0") |
return {
id = "my-plugin",
name = "Example Plugin",
description = "A simple example plugin",
author = "Kairo Developer",
version = "1.0.0",
-- ... commands and views ...
}The following functions are available to all plugins:
kairo.create_task(table): Create a task. Fields:title,description,status,priority,tags(table). Returns created task.kairo.get_task(id): Retrieve a task by ID. Returns task table ornil.kairo.update_task(id, patch_table): Update a task. Returns updated task.kairo.delete_task(id): Permanently remove a task.kairo.list_tasks(filter_table): Query tasks. Filter fields:statuses(table),tag,priority(number),sort.
kairo.notify(message, is_error): Push a message to the status bar.
-- plugins/cleanup.lua
return {
id = "cleanup",
name = "Auto Cleanup",
description = "Removes all DONE tasks with a single command",
commands = {
{
id = "run-cleanup",
title = "Cleanup: Remove Done",
run = function()
local tasks = kairo.list_tasks({statuses = {"done"}})
for _, t in ipairs(tasks) do
kairo.delete_task(t.id)
end
kairo.notify("Cleanup complete!", false)
end
}
}
}-- plugins/focus.lua
return {
id = "focus",
name = "Focus Mode",
views = {
{
id = "active-high-pri",
title = "π₯ Focus",
filter = {
statuses = {"doing"},
min_priority = 0,
sort = "deadline"
}
}
}
}When defining a view filter or listing tasks, you can use: "deadline", "priority", "updated", or "created".
Contributions are welcome! Please see CONTRIBUTING.md for guidelines and CODE_OF_CONDUCT.md for our code of conduct.
Kairo is released under the MIT License.
- Incremental DB-to-UI streaming for large datasets.
- Conflict-free sync via an append-only event log.
- Sandboxed Plugin SDK.
- Smart suggestions and spaced repetition.
- Multi-workspace support with encryption at rest.



