Skip to content

Commit a35a108

Browse files
feat(core): implement unified service layer and automation API
Introduce a centralized `TaskService` to act as the single source of truth for the TUI, Lua plugin system, and CLI. This architectural overhaul enables a stable automation API and a robust event-driven plugin ecosystem. - **Core Architecture**: Refactored internal logic to use `TaskService` instead of direct repository access, decoupling storage from business logic. - **Automation API**: Added a new `kairo api` subcommand providing stable JSON-based control for external scripting and CI/CD integration. - **Plugin System**: - Implemented a unified Lua engine with full CRUD access and event hooks (`task_create`, `task_update`, `task_delete`, `app_start`, `app_stop`). - Standardized plugin structure for custom commands and views. - **UI Improvements**: - Resolved background rendering bleed-through by adding explicit ANSI background colors to all styles and spacers. - Added dynamic view shortcuts (1-9) and a dedicated tag filter key (`f`). - **DevOps**: Updated GoReleaser configuration with modern schema and Homebrew formula support. - Tag input not closable Fixes #4 -script API idea Fixes #5
1 parent f8d9f4f commit a35a108

28 files changed

Lines changed: 1847 additions & 494 deletions

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,3 @@ config.toml
6565
*.zip
6666
.env
6767
.env.*
68-
69-
# Analysis
70-
analysis/

.goreleaser.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# .goreleaser.yaml
2+
# Latest GoReleaser v2 schema
23
version: 2
34

5+
project_name: kairo
6+
47
before:
58
hooks:
69
- go mod tidy
@@ -41,6 +44,7 @@ archives:
4144

4245
checksum:
4346
name_template: 'checksums.txt'
47+
algorithm: sha256
4448

4549
snapshot:
4650
name_template: "{{ .Tag }}-next"
@@ -54,3 +58,20 @@ changelog:
5458
- 'README'
5559
- Merge pull request
5660
- Merge branch
61+
62+
# Modern Homebrew formula
63+
brews:
64+
- name: kairo
65+
repository:
66+
owner: programmersd21
67+
name: homebrew-tap
68+
directory: Formula
69+
homepage: "https://github.com/programmersd21/kairo"
70+
description: "Premium Terminal Task Manager with Lua Extensibility"
71+
license: "MIT"
72+
install: |
73+
bin.install "kairo"
74+
# Install sample plugins
75+
(etc/"kairo/plugins").install Dir["plugins/*.lua"]
76+
test: |
77+
system "#{bin}/kairo version"

CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.1.0]
9+
10+
### Added
11+
- **Unified Extensibility System**: A shared task service layer for TUI, Lua, and CLI.
12+
- **Automation CLI API**: Stable `kairo api` command for external scripting and JSON integration.
13+
- **Enhanced Lua Plugin System**:
14+
- Full Task CRUD access via `kairo` module.
15+
- Event Hook System subscribing to `task_create`, `task_update`, `task_delete`, `app_start`, and `app_stop`.
16+
- Improved Plugin Host with robust error handling and unified engine.
17+
- **App Lifecycle Events**: Proper emission of start/stop events for plugin orchestration.
18+
- **Dynamic View Shortcuts**: `1-9` keys now switch to the corresponding tab index, working for all built-in and plugin-provided views.
19+
- **Specific Tag Filter Key**: `f` now specifically switches to the Tag View and opens the filter input modal.
20+
21+
### Fixed
22+
- **Background Rendering Bleed-Through**: Resolved a visual bug where the terminal's default background color showed through in whitespace regions, creating inconsistent visuals across the entire viewport.
23+
- **Root Cause**: Inline spacer strings (`strings.Repeat(" ", N)`) in the header, footer, and task rows were plain text without ANSI background escape codes. Additionally, multiple Lip Gloss styles (`Muted`, `Accent`, `Badge*`, `Tab*`) were defined without `.Background()`, causing their ANSI reset codes to clear the container's background.
24+
- Added explicit `.Background(t.Bg)` to all content-level styles (`Muted`, `Accent`, `TabActive`, `TabInactive`, `Badge`, `BadgeGood`, `BadgeWarn`, `BadgeBad`, `BadgeMuted`).
25+
- Wrapped all inline spacer strings in styled renders with the theme background color.
26+
- Added background to the detail view outer container.
27+
- The fix is robust across resizing, scrolling, theme switching, and all UI modes.
28+
### Changed
29+
- Refactored internal architecture to use `TaskService` as the single source of truth.
30+
- Standardized Lua plugin structure with metadata, commands, and views.
31+
- Improved CLI consistency with new `api` subcommand flags and JSON support.
32+
833
## [1.0.4]
934

1035
### Added

README.md

Lines changed: 98 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<div align="center">
22

3-
# 📝 Kairo
3+
# 📝 Kairo — 🌿 Minimal, powerful task management.
44

5-
![Main App](screenshots/app.png)
5+
![Main App](screenshots/thumbnail.png)
66

77
[![Release](https://img.shields.io/github/v/release/programmersd21/kairo?sort=semver&style=for-the-badge&logo=github&color=7c3aed)](https://github.com/programmersd21/kairo/releases)
88
[![CI](https://img.shields.io/github/actions/workflow/status/programmersd21/kairo/ci.yml?branch=main&style=for-the-badge&logo=githubactions&logoColor=white&color=2563eb)](https://github.com/programmersd21/kairo/actions)
@@ -26,10 +26,12 @@ with the sophistication of a *modern, premium design system*.
2626
🎯 **Instant Responsiveness** — Sub-millisecond task searching and navigation
2727
🎨 **Premium UI Design** — Modern color palette with accessibility at its core
2828
⌨️ **Keyboard-First** — Complete control without ever touching a mouse
29+
🖥️ **Seamless Rendering** — Pixel-perfect background fills the entire viewport, no terminal bleed-through
2930
🔐 **Offline-First** — Your data lives locally in SQLite, always under your control
3031
🔗 **Git-Backed Sync** — Optional distributed sync leveraging Git's architecture
31-
🧩 **Extensible** — Lua-based plugins for custom workflows
32+
🧩 **Extensible**Unified Lua plugin system and CLI automation API
3233
📱 **Responsive Layout** — Gracefully adapts to any terminal size
34+
🤖 **Automation-Friendly** — Headless API for external scripts and CI/CD
3335

3436
Built with [Bubble Tea](https://github.com/charmbracelet/bubbletea) (TUI framework), [Lip Gloss](https://github.com/charmbracelet/lipgloss) (terminal styling), and SQLite (local storage).
3537

@@ -39,16 +41,86 @@ Built with [Bubble Tea](https://github.com/charmbracelet/bubbletea) (TUI framewo
3941

4042
| Feature | Description |
4143
|---------|-------------|
42-
| **Task Engine** | Title, description (Markdown), tags, priority levels, deadlines, status tracking |
44+
| **Task Service** | Single source of truth for TUI, Lua, and CLI automation |
45+
| **Lua Plugins** | Native first-class scripting with event hooks (GopherLua) |
46+
| **Automation API** | Stable CLI interface for external control and JSON integration |
47+
| **Event Hooks** | React to task creation, updates, and app lifecycle events |
4348
| **Smart Filtering** | Multiple views: Inbox, Today, Upcoming, Completed, by Tag, by Priority |
4449
| **Fuzzy Search** | Lightning-fast command palette with ranked results |
4550
| **Strike Animation** | Visual feedback when completing tasks with 'z' |
4651
| **Offline Storage** | SQLite with WAL for reliability and concurrent access |
4752
| **Git Sync** | Optional repository-backed sync with per-task JSON files |
48-
| **Lua Plugins** | Extend the app with custom commands and views |
4953
| **Import/Export** | JSON and Markdown support for data portability |
50-
| **Modern Themes** | 4 built-in themes (Midnight, Dracula, Nord, Paper) with user customization |
51-
| **Minimalist UI** | Breathable, clean design system with standard Unicode compatibility |
54+
55+
---
56+
57+
## 🤖 Automation & CLI API
58+
59+
Kairo provides a stable CLI API for external automation. Every operation available in the TUI can be performed via the `api` subcommand.
60+
61+
### Usage
62+
63+
```bash
64+
# List tasks with a specific tag
65+
kairo api list --tag work
66+
67+
# Create a new task
68+
kairo api create --title "Finish report" --priority 1
69+
70+
# Update a task
71+
kairo api update --id <task-id> --status done
72+
73+
# Advanced JSON interface
74+
kairo api --json '{"action": "create", "payload": {"title": "API Task", "tags": ["bot"]}}'
75+
```
76+
77+
---
78+
79+
## 🔌 Plugins (Lua)
80+
81+
Extend Kairo with custom logic, event hooks, commands, and views using Lua.
82+
83+
### Plugin Structure
84+
85+
```lua
86+
-- plugins/my-plugin.lua
87+
local plugin = {
88+
id = "my-plugin",
89+
name = "My Plugin",
90+
description = "Reacts to tasks",
91+
version = "1.0.0",
92+
}
93+
94+
-- Hook into events
95+
kairo.on("task_create", function(event)
96+
kairo.notify("New task: " .. event.task.title)
97+
end)
98+
99+
-- Register custom commands
100+
plugin.commands = {
101+
{ id = "hello", title = "Say Hello", run = function() kairo.notify("Hello!") end }
102+
}
103+
104+
return plugin
105+
```
106+
107+
### Supported Events
108+
- `task_create`
109+
- `task_update`
110+
- `task_delete`
111+
- `app_start`
112+
- `app_stop`
113+
114+
### Lua API Reference
115+
116+
| Method | Description |
117+
|--------|-------------|
118+
| `kairo.create_task(table)` | Create a new task |
119+
| `kairo.update_task(id, table)` | Update an existing task |
120+
| `kairo.delete_task(id)` | Delete a task |
121+
| `kairo.list_tasks(filter)` | List tasks with optional filter |
122+
| `kairo.on(event, function)` | Register an event listener |
123+
| `kairo.notify(msg, is_error)` | Send a notification to the UI |
52124

53125
---
54126

@@ -59,6 +131,7 @@ Kairo features a **minimalist design system** optimized for clarity and focus.
59131
### Design Philosophy
60132

61133
- **Breathable Layout** — Reduced padding and thin borders for a clean, modern look
134+
- **Seamless Backdrop** — Custom rendering engine ensures the theme background covers the entire terminal window
62135
- **Instant Feedback** — Smooth strikethrough animations when completing tasks
63136
- **Keyboard-First** — All interactions optimized for speed
64137
- **High Compatibility** — Uses standard Unicode symbols for consistent rendering across all terminals
@@ -82,18 +155,16 @@ Kairo features a **minimalist design system** optimized for clarity and focus.
82155
| `?` | ❓ Show help menu |
83156
| `q` | ❌ Quit |
84157

85-
### View Filters
158+
### View Shortcuts
86159

87160
| Shortcut | View |
88161
|----------|------|
89-
| `1` | **Inbox** — Active tasks |
90-
| `2` | **Today** — Due today |
91-
| `3` | **Upcoming** — Future deadlines |
92-
| `4` | **Tags** — Filter by tag |
93-
| `5` | **Priority** — Filter by priority |
162+
| `1` - `9` | **Switch Views** — Instant access to all tabs (Inbox, Today, Plugins, etc.) |
163+
| `f` | **Tag Filter** — Quickly jump to Tag View and filter by name |
164+
| `tab` / `shift+tab` | **Cycle Views** — Move through all available tabs |
94165

95166
### Pro Tips
96-
- Press `4` to open the **tag filter input modal** for direct tag entry
167+
- Press `f` to open the **tag filter input modal** for direct tag entry
97168
- Type tag name and press `enter` to apply filter, or `esc` to cancel
98169
- Type `#tag` in the command palette to jump to a specific tag
99170
- Type `pri:0` to filter tasks by priority level
@@ -153,6 +224,7 @@ Kairo is built with a modular architecture designed for performance, extensibili
153224

154225
| Component | Role |
155226
|-----------|------|
227+
| **Task Service** | Single source of truth for TUI, Lua, and CLI automation |
156228
| **UI Layer** ([Bubble Tea](https://github.com/charmbracelet/bubbletea)) | Elm-inspired TUI framework with state-machine pattern for mode management |
157229
| **Storage** (SQLite) | Pure Go database with WAL for reliability and concurrent access |
158230
| **Sync Engine** (Git) | Distributed "no-backend" sync with per-task JSON files |
@@ -162,7 +234,7 @@ Kairo is built with a modular architecture designed for performance, extensibili
162234
### Data Flow
163235

164236
```
165-
User Input → Bubble Tea Loop → Active Component
237+
User Input/API/LuaTask Service → Hooks System
166238
167239
Immediate DB Persistence → Optional Git Sync
168240
@@ -171,76 +243,18 @@ UI Re-render → Instant User Feedback
171243

172244
---
173245

174-
## 🔌 Plugins (Lua)
175-
176-
Extend Kairo with custom commands and views using Lua. Place `.lua` files in your plugins directory.
177-
178-
### Plugin Metadata
179-
180-
```lua
181-
return {
182-
id = "my-plugin",
183-
name = "My Custom Plugin",
184-
description = "Does something awesome",
185-
author = "You",
186-
version = "1.0.0",
187-
-- commands and views defined below
188-
}
189-
```
190-
191-
### API: Tasks
192-
193-
```lua
194-
-- Create, read, update, delete tasks
195-
kairo.create_task({title, description, status, priority, tags})
196-
kairo.get_task(id)
197-
kairo.update_task(id, {title, status, ...})
198-
kairo.delete_task(id)
199-
kairo.list_tasks({statuses, tag, priority, sort})
200-
```
201-
202-
### API: UI
203-
204-
```lua
205-
-- Send notifications to the user
206-
kairo.notify(message, is_error)
207-
```
208-
209-
### Example: Cleanup Command
210-
211-
```lua
212-
-- plugins/cleanup.lua
213-
return {
214-
id = "cleanup",
215-
name = "Cleanup Done Tasks",
216-
description = "Removes all completed tasks",
217-
commands = {
218-
{
219-
id = "run-cleanup",
220-
title = "Cleanup: Remove Done",
221-
run = function()
222-
local tasks = kairo.list_tasks({statuses = {"done"}})
223-
for _, t in ipairs(tasks) do
224-
kairo.delete_task(t.id)
225-
end
226-
kairo.notify("Cleanup complete!", false)
227-
end
228-
}
229-
}
230-
}
231-
```
232-
233-
---
234-
235246
## 🌴 Project Structure
236247

237248
```
238249
kairo/
239-
├── cmd/kairo/ # Main entry point
250+
├── cmd/kairo/ # Main entry point (TUI & API)
240251
├── internal/
252+
│ ├── service/ # Core Task Service (Single source of truth)
253+
│ ├── lua/ # Lua engine & bindings
254+
│ ├── api/ # CLI API implementation
255+
│ ├── hooks/ # Event system
241256
│ ├── app/ # Application state & messages
242257
│ ├── core/ # Task model & core logic
243-
│ ├── config/ # Configuration parsing
244258
│ ├── storage/ # SQLite repository
245259
│ ├── sync/ # Git sync engine
246260
│ ├── search/ # Fuzzy search index
@@ -278,6 +292,12 @@ We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guid
278292

279293
---
280294

295+
## 💙 Community Legend(s)
296+
297+
- **@Tornado300** — Contributed significantly by reporting issues that led to multiple critical bug fixes.
298+
299+
---
300+
281301
## 📜 License
282302

283303
Kairo is released under the [MIT License](LICENSE).

VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.4
1+
1.1.0

0 commit comments

Comments
 (0)