package main import ( "context" "errors" "flag" "log" "net/http" "os" "os/signal" "syscall" "time" "ai-workflow-skill/internal/app" "ai-workflow-skill/packages/coord-core/db" "ai-workflow-skill/internal/httpapi" ) func main() { var ( dbPath string listen string shutdown time.Duration ) flag.StringVar(&dbPath, "db", ".agents/coord.db", "SQLite database path") flag.StringVar(&listen, "listen", ":8080", "HTTP listen address") flag.DurationVar(&shutdown, "shutdown-timeout", 5*time.Second, "Graceful shutdown timeout") flag.Parse() ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() sqlDB, err := db.Open(ctx, dbPath) if err != nil { log.Fatalf("open database: %v", err) } defer sqlDB.Close() if err := db.ApplyMigrations(ctx, sqlDB); err != nil { log.Fatalf("apply migrations: %v", err) } webApp := app.NewWebService(sqlDB) server := &http.Server{ Addr: listen, Handler: httpapi.NewRouter(webApp), ReadHeaderTimeout: 5 * time.Second, } go func() { <-ctx.Done() shutdownCtx, cancel := context.WithTimeout(context.Background(), shutdown) defer cancel() if err := server.Shutdown(shutdownCtx); err != nil && !errors.Is(err, http.ErrServerClosed) { log.Printf("http shutdown: %v", err) } }() log.Printf("orchd listening on %s", listen) if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { log.Fatalf("serve http api: %v", err) } }