package main import ( "fmt" "net/http" "os" "woke/api" "woke/db" "woke/player" "woke/scheduler" "woke/ui" tea "github.com/charmbracelet/bubbletea" ) const helpText = `woke - TUI alarm clock with REST API Usage: woke Start the TUI (API server runs on :9119) woke --help Show this help API endpoints (http://localhost:9119): List alarms: curl http://localhost:9119/api/alarms Get alarm: curl http://localhost:9119/api/alarms/1 Create alarm (one-shot): curl -X POST http://localhost:9119/api/alarms \ -H 'Content-Type: application/json' \ -d '{"name": "Standup", "time": "09:00", "trigger": "once"}' Create alarm (cron, weekdays at 7:30): curl -X POST http://localhost:9119/api/alarms \ -H 'Content-Type: application/json' \ -d '{"name": "Morning", "time": "07:30", "trigger": "30 7 * * 1-5"}' Update alarm: curl -X PUT http://localhost:9119/api/alarms/1 \ -H 'Content-Type: application/json' \ -d '{"name": "New name", "time": "08:00"}' Toggle alarm on/off: curl -X PATCH http://localhost:9119/api/alarms/1/toggle Delete alarm: curl -X DELETE http://localhost:9119/api/alarms/1 TUI keybindings: j/k Navigate alarms a Add alarm e Edit alarm d Delete alarm space Toggle enabled c Settings q Quit ` func main() { if len(os.Args) > 1 && (os.Args[1] == "--help" || os.Args[1] == "-h") { fmt.Print(helpText) os.Exit(0) } store, err := db.Open() if err != nil { fmt.Fprintf(os.Stderr, "Failed to open database: %v\n", err) os.Exit(1) } defer store.Close() pl := player.New() sched := scheduler.New(store) sched.Start() defer sched.Stop() model := ui.NewModel(store, sched, pl) p := tea.NewProgram(model, tea.WithAltScreen()) // Start HTTP API server — notify TUI on mutations via p.Send srv := api.New(store, func() { p.Send(ui.AlarmsChangedMsg{}) }) go func() { addr := ":9119" fmt.Fprintf(os.Stderr, "API server listening on %s\n", addr) if err := http.ListenAndServe(addr, srv.Handler()); err != nil { fmt.Fprintf(os.Stderr, "API server error: %v\n", err) } }() if _, err := p.Run(); err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } }