package main import ( "context" "errors" "fmt" "log/slog" "os" "path/filepath" "strings" "git.toki-labs.com/toki/gito/services/core/internal/config" "git.toki-labs.com/toki/gito/services/core/internal/controlplane" "git.toki-labs.com/toki/gito/services/core/internal/core" "git.toki-labs.com/toki/gito/services/core/internal/storage" "git.toki-labs.com/toki/gito/services/core/internal/worker" ) // migrationSQL loads the initial migration SQL from well-known paths relative // to the executable or common working directories, so the server/worker works // regardless of the cwd it is launched from. func migrationSQL() string { exe, err := os.Executable() if err != nil { exe = "" } candidates := []string{ // set explicitly via env os.Getenv("GITO_MIGRATION_PATH"), // next to the binary (bin/gito-server → bin/../migrations/...) filepath.Join(filepath.Dir(exe), "migrations", "00001_initial.sql"), // launched from repo root filepath.Join("services", "core", "migrations", "00001_initial.sql"), // launched from services/core filepath.Join("migrations", "00001_initial.sql"), } for _, p := range candidates { if p == "" { continue } data, err := os.ReadFile(p) if err == nil { return string(data) } } return "" } // pgAgentRunInputLoader loads durable agent run inputs from the Postgres store // and converts them to the worker input type. type pgAgentRunInputLoader struct { store storage.AgentRunInputStore } func (l *pgAgentRunInputLoader) LoadAgentRunInput(ctx context.Context, op core.Operation) (worker.AgentRunInput, error) { durable, err := l.store.GetAgentRunInput(ctx, op.ID) if err != nil { if errors.Is(err, storage.ErrAgentRunInputNotFound) { return worker.AgentRunInput{}, fmt.Errorf("agent run input not found for operation %s: %w", op.ID, err) } return worker.AgentRunInput{}, fmt.Errorf("load agent run input: %w", err) } if strings.TrimSpace(durable.WorkspacePath) == "" || strings.TrimSpace(durable.Branch) == "" || strings.TrimSpace(durable.Instruction) == "" || strings.TrimSpace(durable.ExpectedRevision) == "" { return worker.AgentRunInput{}, fmt.Errorf("agent run input for %s is missing required fields (workspace_path, branch, instruction, expected_revision)", op.ID) } return worker.AgentRunInput{ OperationID: durable.OperationID, RepoID: durable.RepoID, Branch: durable.Branch, WorkspacePath: durable.WorkspacePath, Instruction: durable.Instruction, PolicyContext: durable.PolicyContext, ExpectedRevision: durable.ExpectedRevision, }, nil } func main() { cfg := config.Load() logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) dsn := os.Getenv("DATABASE_URL") if dsn == "" { logger.Error("DATABASE_URL is required") os.Exit(1) } pgStore, err := storage.NewPgStore(context.Background(), dsn, migrationSQL()) if err != nil { logger.Error("failed to open postgres store", "error", err) os.Exit(1) } logger.Info("postgres store connected") defer pgStore.Close() publisher := controlplane.NewOutboxBroadcaster(pgStore.OperationEvents()) scanner := controlplane.NewRuntimeWithStore(publisher, pgStore) iopEndpoint := strings.TrimSpace(cfg.IOPEndpoint) if iopEndpoint == "" { logger.Info("IOP_ENDPOINT not configured; agent_run picking disabled") // Run with nil picker so worker logs the disabled message and exits cleanly. w := worker.NewRunner(cfg, logger, nil, nil, scanner) if err := w.Run(); err != nil { logger.Error("worker stopped", "error", err) os.Exit(1) } return } inputLoader := &pgAgentRunInputLoader{store: pgStore.AgentRunInputs()} invoker := worker.NewHTTPInvoker(iopEndpoint) w := worker.NewRunnerWithDependencies(cfg, logger, nil, nil, worker.RunnerDependencies{ OperationStore: pgStore.Operations(), OperationEventStore: pgStore.OperationEvents(), AgentRunPicker: pgStore.Operations(), AgentRunInputLoader: inputLoader, AgentRunInvoker: invoker, RevisionScanner: scanner, }) if err := w.Run(); err != nil { logger.Error("worker stopped", "error", err) os.Exit(1) } }