Skip to content

Commit a53e417

Browse files
feat: implement automatic startup update check
- Add automatic GitHub release check on startup - Display update notification in the footer with version delta - Skip update checks for development builds - Update version to 1.1.8 - Expand built-in themes from 12 to 32 - Add interactive demo gif to README docs: update documentation for 1.1.8 - Update CHANGELOG.md with new features - Update README.md with new theme list and demo gif - Update VERSION.txt to 1.1.8
1 parent 692316b commit a53e417

8 files changed

Lines changed: 76 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ 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.8]
9+
10+
### Added
11+
- **Startup Update Check**: Kairo now automatically checks for new releases on GitHub during startup. If a newer version is found, a notification appears in the footer with the version delta (e.g., `v1.1.7 → v1.1.8`) and instructions to update.
12+
- **Smart Update Logic**: Update checks are intelligently skipped when running a development build (`dev`) to minimize noise for contributors.
13+
- **Interactive Demo**: Added a new, high-fidelity demo GIF to the documentation for better visual clarity of the application's workflow and animations.
14+
815
## [1.1.7]
916

1017
### Added

README.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
<div align="center">
22

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

5-
![Main App](screenshots/thumbnail.png)
5+
### 🌿 Minimal, powerful task management for the modern terminal.
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)
99
[![Go Report Card](https://img.shields.io/badge/go%20report-A%2B-brightgreen?style=for-the-badge&logo=go&logoColor=white&color=10b981)](https://goreportcard.com/report/github.com/programmersd21/kairo)
1010
[![License: MIT](https://img.shields.io/badge/License-MIT-f59e0b?style=for-the-badge&logo=open-source-initiative&logoColor=white)](https://opensource.org/licenses/MIT)
1111

12+
---
13+
14+
| **Static Overview** | **Interactive Demo** |
15+
|:---:|:---:|
16+
| ![Main App](screenshots/thumbnail.png) | ![Demo](screenshots/demo.gif) |
17+
1218
**⌛ Time, executed well.**
1319

1420
</div>
@@ -108,6 +114,9 @@ kairo update
108114
Downloads the latest GitHub Release for your OS/arch, verifies it against `checksums.txt`, and safely replaces the installed binary.
109115
On Windows, Kairo will automatically close to apply the update; simply re-run `kairo` once the terminal returns.
110116

117+
**Startup Notifications:**
118+
Kairo automatically checks for updates on startup. If a newer version is available, a notification will appear in the footer (e.g., `Update: v1.1.7 → v1.1.8`) directing you to run the update command.
119+
111120
---
112121

113122
## 🤖 Automation & CLI API
@@ -217,6 +226,8 @@ return plugin
217226

218227
Kairo features a **minimalist design system** optimized for clarity and focus.
219228

229+
![Main App](screenshots/thumbnail.png)
230+
220231
### Design Philosophy
221232

222233
- **Breathable Layout** — Reduced padding and thin borders for a clean, modern look
@@ -291,9 +302,10 @@ cp configs/kairo.example.toml ~/.config/kairo/config.toml
291302
```
292303

293304
Then edit to customize:
294-
- **Theme selection** — Choose from 12 built-in themes:
295-
- **Dark:** Catppuccin (Default), Midnight, Aurora, Cyberpunk, Dracula, Nord
296-
- **Light:** Vanilla, Solarized, Rose, Matcha, Cloud, Sepia
305+
- **Theme selection** — Choose from 32 built-in themes:
306+
- **Premium Dark:** `catppuccin` (Default), `midnight`, `aurora`, `cyberpunk`, `dracula`, `nord`, `obsidian_bloom`, `neon_reef`, `carbon_sunset`, `vanta_aurora`, `plasma_grape`, `midnight_jade`, `synthwave_minimal`, `graphite_matcha`
307+
- **Premium Light:** `vanilla`, `solarized`, `rose`, `matcha`, `cloud`, `sepia`, `cloud_dancer`, `sakura_sand`, `olive_mist`, `terracotta_air`, `vanilla_sky`, `peach_fuzz_neo`, `coastal_drift`, `matcha_latte`
308+
- **Hybrid/Specialized:** `digital_lavender`, `neo_mint_system`, `sunset_gradient_pro`, `forest_sanctuary`
297309
- **Keybindings** — Rebind any keyboard shortcut
298310
- **View ordering** — Customize your task view tabs
299311
- **Sync settings** — Configure Git repository sync

VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.1.7
1+
1.1.8

internal/app/model.go

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"github.com/programmersd21/kairo/internal/ui/tasklist"
3535
"github.com/programmersd21/kairo/internal/ui/theme"
3636
"github.com/programmersd21/kairo/internal/ui/theme_menu"
37+
"github.com/programmersd21/kairo/internal/updater"
3738
"github.com/programmersd21/kairo/internal/util"
3839
)
3940

@@ -126,6 +127,8 @@ type Model struct {
126127
statusText string
127128
isErr bool
128129

130+
updateAvailable *updateAvailableMsg
131+
129132
syncEngine *ksync.Engine
130133

131134
plugHost *plugins.Host
@@ -232,7 +235,7 @@ func applyThemeOverride(t theme.Theme, o config.ThemeConfig) theme.Theme {
232235
}
233236

234237
func (m *Model) Init() tea.Cmd {
235-
cmds := []tea.Cmd{m.loadTagsCmd(), m.loadTasksCmd(), m.loadAllTasksCmd()}
238+
cmds := []tea.Cmd{m.loadTagsCmd(), m.loadTasksCmd(), m.loadAllTasksCmd(), m.checkUpdateCmd()}
236239
if m.cfg.App.Rainbow {
237240
cmds = append(cmds, m.rainbowTickCmd())
238241
}
@@ -462,6 +465,10 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
462465
m.isErr = true
463466
}
464467
return m, nil
468+
469+
case updateAvailableMsg:
470+
m.updateAvailable = &x
471+
return m, nil
465472
}
466473

467474
if km, ok := msg.(tea.KeyMsg); ok {
@@ -938,7 +945,22 @@ func (m *Model) renderFooter() string {
938945
if m.syncEngine != nil && m.syncEngine.Enabled() {
939946
syncStatus = styles.IconSync + " "
940947
}
941-
right = m.s.Muted.Render(syncStatus + buildinfo.VersionTag() + " ")
948+
949+
versionText := buildinfo.VersionTag()
950+
if m.updateAvailable != nil {
951+
cur := m.updateAvailable.Current
952+
if !strings.HasPrefix(cur, "v") {
953+
cur = "v" + cur
954+
}
955+
lat := m.updateAvailable.Latest
956+
if !strings.HasPrefix(lat, "v") {
957+
lat = "v" + lat
958+
}
959+
versionText = fmt.Sprintf("Update: %s → %s (run `kairo update`)", cur, lat)
960+
right = m.s.Muted.Foreground(m.s.Theme.Accent).Bold(true).Render(syncStatus + versionText + " ")
961+
} else {
962+
right = m.s.Muted.Render(syncStatus + versionText + " ")
963+
}
942964
}
943965

944966
line := render.BarLine(left, right, m.width, m.s.Theme.Bg)
@@ -1275,6 +1297,27 @@ func (m *Model) syncNowCmd() tea.Cmd {
12751297
}
12761298
}
12771299

1300+
func (m *Model) checkUpdateCmd() tea.Cmd {
1301+
return func() tea.Msg {
1302+
v := buildinfo.EffectiveVersion()
1303+
if v == "dev" {
1304+
return nil
1305+
}
1306+
cfg := updater.DefaultConfig()
1307+
res, _, err := cfg.Check(m.ctx, v)
1308+
if err != nil {
1309+
return nil // Silently fail update check
1310+
}
1311+
if res.Update {
1312+
return updateAvailableMsg{
1313+
Current: res.Current,
1314+
Latest: res.Latest,
1315+
}
1316+
}
1317+
return nil
1318+
}
1319+
}
1320+
12781321
func openURLCmd(url string) tea.Cmd {
12791322
return func() tea.Msg {
12801323
var cmd *exec.Cmd

internal/app/msg.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ type pluginChangedMsg struct{}
1919

2020
type syncDoneMsg struct{ Err error }
2121

22+
type updateAvailableMsg struct {
23+
Current string
24+
Latest string
25+
}
26+
2227
type rainbowTickMsg struct{}
2328

2429
type strikeAnimationTickMsg struct{ TaskID string }

internal/lua/engine.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func (e *Engine) SetupKairoAPI(L *lua.LState) {
5555
L.SetField(kairo, "notify", L.NewFunction(e.luaNotify))
5656

5757
// Meta
58-
L.SetField(kairo, "version", lua.LString("1.1.7"))
58+
L.SetField(kairo, "version", lua.LString("1.1.8"))
5959

6060
// Set as global
6161
L.SetGlobal("kairo", kairo)

screenshots/demo.gif

23.3 MB
Loading

screenshots/thumbnail.png

130 KB
Loading

0 commit comments

Comments
 (0)