feat: initial gosleep-timer implementation

Go TUI sleep timer with modular architecture.
- Config: YAML-based, profile inheritance, auto WM detection
- Engine: timer, executor, stage pipeline (pre→timer→post)
- Modules: workspace (niri/hyprland/kde), media, lock, kill,
  notify, sound, brightness, mute, custom, script
- TUI: bubbletea app with profiles, module toggles, progress bar
- CLI: run, list-profiles, export, import, history, stats
- History: JSONL log with statistics
- QR: config export as ASCII QR
This commit is contained in:
2026-07-03 01:43:22 +02:00
commit 8501fd074c
34 changed files with 3401 additions and 0 deletions
+53
View File
@@ -0,0 +1,53 @@
package modules
import "github.com/forust/gosleep-timer/config"
var registry []Module
func Register(m Module) {
registry = append(registry, m)
}
func GetAll() []Module {
return registry
}
func GetEnabled(cfg *config.Modules) []Module {
var enabled []Module
for _, m := range registry {
if m.Enabled(cfg) {
enabled = append(enabled, m)
}
}
return enabled
}
func CollectPreCmds(ctx *ModuleContext) []string {
var cmds []string
for _, m := range GetEnabled(ctx.Config) {
cmds = append(cmds, m.BuildCmds(ctx, StagePre)...)
}
return cmds
}
func CollectPostCmds(ctx *ModuleContext) []string {
var cmds []string
for _, m := range GetEnabled(ctx.Config) {
cmds = append(cmds, m.BuildCmds(ctx, StagePost)...)
}
return cmds
}
func ValidateAll() []error {
var errs []error
for _, m := range registry {
if err := m.Validate(); err != nil {
errs = append(errs, err)
}
}
return errs
}
func Init() {
// registry starts empty; modules register themselves via init() or Register()
}