Documentation
¶
Index ¶
- Constants
- Variables
- func DefaultDBPath() string
- func ExtractRepoNameFromIdentity(identity string) string
- func GenerateUUID() string
- func ParseVerdict(output string) string
- type AgentStats
- type BatchPRRef
- type BatchReviewResult
- type BranchListResult
- type BranchWithCount
- type CIPRBatch
- type CIPRReview
- type Commit
- type ComponentHealth
- type DB
- func (db *DB) AddComment(commitID int64, responder, response string) (*Response, error)
- func (db *DB) AddCommentToJob(jobID int64, responder, response string) (*Response, error)
- func (db *DB) BackfillRepoIdentities() (int, error)
- func (db *DB) BackfillSourceMachineID() error
- func (db *DB) BackfillVerdictBool() (int, error)
- func (db *DB) CancelClosedPRBatches(githubRepo string, prNumber int) ([]int64, error)
- func (db *DB) CancelJob(jobID int64) error
- func (db *DB) CancelJobWithError(jobID int64, errMsg string) error
- func (db *DB) CancelSupersededBatches(githubRepo string, prNumber int, newHeadSHA string) ([]int64, error)
- func (db *DB) ClaimBatchForSynthesis(batchID int64) (bool, error)
- func (db *DB) ClaimJob(workerID string) (*ReviewJob, error)
- func (db *DB) ClearAllSyncedAt() error
- func (db *DB) CompleteFixJob(jobID int64, agent, prompt, output, patch string) error
- func (db *DB) CompleteJob(jobID int64, agent, prompt, output string) error
- func (db *DB) CountBatchJobs(batchID int64) (int, error)
- func (db *DB) CountJobStats(repoFilter string, opts ...ListJobsOption) (JobStats, error)
- func (db *DB) CountStalledJobs(threshold time.Duration) (int, error)
- func (db *DB) CreateCIBatch(githubRepo string, prNumber int, headSHA string, totalJobs int) (*CIPRBatch, bool, error)
- func (db *DB) DeleteCIBatch(batchID int64) error
- func (db *DB) DeleteEmptyBatches() (int, error)
- func (db *DB) DeleteRepo(repoID int64, cascade bool) error
- func (db *DB) EnqueueJob(opts EnqueueOpts) (*ReviewJob, error)
- func (db *DB) FailJob(jobID int64, workerID string, errorMsg string) (bool, error)
- func (db *DB) FailoverJob(jobID int64, workerID, backupAgent, backupModel string) (bool, error)
- func (db *DB) FinalizeBatch(batchID int64) error
- func (db *DB) FindRepo(identifier string) (*Repo, error)
- func (db *DB) FindReusableSessionCandidate(repoID int64, branch, agent, reviewType, worktreePath string) (*ReviewJob, error)
- func (db *DB) FindReusableSessionCandidates(repoID int64, branch, agent, reviewType, worktreePath string, limit int) ([]ReviewJob, error)
- func (db *DB) GetAllCommentsForJob(jobID, commitID int64, fallbackSHA string) ([]Response, error)
- func (db *DB) GetAllReviewsForGitRef(gitRef string) ([]Review, error)
- func (db *DB) GetBatchJobIDs(batchID int64) ([]int64, error)
- func (db *DB) GetBatchReviews(batchID int64) ([]BatchReviewResult, error)
- func (db *DB) GetCIBatchByJobID(jobID int64) (*CIPRBatch, error)
- func (db *DB) GetCIReviewByJobID(jobID int64) (*CIPRReview, error)
- func (db *DB) GetCommentsForCommit(commitID int64) ([]Response, error)
- func (db *DB) GetCommentsForCommitSHA(sha string) ([]Response, error)
- func (db *DB) GetCommentsForJob(jobID int64) ([]Response, error)
- func (db *DB) GetCommentsToSync(machineID string, limit int) ([]SyncableResponse, error)
- func (db *DB) GetCommitByID(id int64) (*Commit, error)
- func (db *DB) GetCommitByRepoAndSHA(repoID int64, sha string) (*Commit, error)
- func (db *DB) GetCommitBySHA(sha string) (*Commit, error)
- func (db *DB) GetExpiredBatches(timeout time.Duration) ([]CIPRBatch, error)
- func (db *DB) GetJobByID(id int64) (*ReviewJob, error)
- func (db *DB) GetJobCounts() (queued, running, done, failed, canceled, applied, rebased int, err error)
- func (db *DB) GetJobRetryCount(jobID int64) (int, error)
- func (db *DB) GetJobsToSync(machineID string, limit int) ([]SyncableJob, error)
- func (db *DB) GetJobsWithReviewsByIDs(jobIDs []int64) (map[int64]JobWithReview, error)
- func (db *DB) GetKnownJobUUIDs() ([]string, error)
- func (db *DB) GetMachineID() (string, error)
- func (db *DB) GetNonTerminalBatchJobIDs(batchID int64) ([]int64, error)
- func (db *DB) GetOrCreateCommit(repoID int64, sha, author, subject string, timestamp time.Time) (*Commit, error)
- func (db *DB) GetOrCreateCommitByRepoAndSHA(repoID int64, sha, author, subject string, timestamp time.Time) (int64, error)
- func (db *DB) GetOrCreateRepo(rootPath string, identity ...string) (*Repo, error)
- func (db *DB) GetOrCreateRepoByIdentity(identity string) (int64, error)
- func (db *DB) GetPendingBatchPRs(githubRepo string) ([]BatchPRRef, error)
- func (db *DB) GetRecentReviewsForRepo(repoID int64, limit int) ([]Review, error)
- func (db *DB) GetRepoByID(id int64) (*Repo, error)
- func (db *DB) GetRepoByIdentity(identity string) (*Repo, error)
- func (db *DB) GetRepoByIdentityCaseInsensitive(identity string) (*Repo, error)
- func (db *DB) GetRepoByName(name string) (*Repo, error)
- func (db *DB) GetRepoByPath(rootPath string) (*Repo, error)
- func (db *DB) GetRepoStats(repoID int64) (*RepoStats, error)
- func (db *DB) GetReviewByCommitSHA(sha string) (*Review, error)
- func (db *DB) GetReviewByID(reviewID int64) (*Review, error)
- func (db *DB) GetReviewByJobID(jobID int64) (*Review, error)
- func (db *DB) GetReviewsToSync(machineID string, limit int) ([]SyncableReview, error)
- func (db *DB) GetStaleBatches() ([]CIPRBatch, error)
- func (db *DB) GetSummary(opts SummaryOptions) (*Summary, error)
- func (db *DB) GetSyncState(key string) (string, error)
- func (db *DB) HasCIBatch(githubRepo string, prNumber int, headSHA string) (bool, error)
- func (db *DB) HasCIReview(githubRepo string, prNumber int, headSHA string) (bool, error)
- func (db *DB) HasMeaningfulBatchResult(batchID int64) (bool, error)
- func (db *DB) IncrementBatchCompleted(batchID int64) (*CIPRBatch, error)
- func (db *DB) IncrementBatchFailed(batchID int64) (*CIPRBatch, error)
- func (db *DB) IsBatchExpired(batchID int64, timeout time.Duration) (bool, error)
- func (db *DB) IsBatchStale(batchID int64) (bool, error)
- func (db *DB) LatestBatchTimeForPR(githubRepo string, prNumber int) (time.Time, error)
- func (db *DB) ListBranchesWithCounts(repoPaths []string) (*BranchListResult, error)
- func (db *DB) ListJobs(statusFilter string, repoFilter string, limit, offset int, ...) ([]ReviewJob, error)
- func (db *DB) ListRepos() ([]Repo, error)
- func (db *DB) ListReposWithReviewCounts(opts ...ListReposOption) ([]RepoWithCount, int, error)
- func (db *DB) MarkCommentSynced(responseID int64) error
- func (db *DB) MarkCommentsSynced(responseIDs []int64) error
- func (db *DB) MarkJobApplied(jobID int64) error
- func (db *DB) MarkJobRebased(jobID int64) error
- func (db *DB) MarkJobSynced(jobID int64) error
- func (db *DB) MarkJobsSynced(jobIDs []int64) error
- func (db *DB) MarkReviewClosed(reviewID int64, closed bool) error
- func (db *DB) MarkReviewClosedByJobID(jobID int64, closed bool) error
- func (db *DB) MarkReviewSynced(reviewID int64) error
- func (db *DB) MarkReviewsSynced(reviewIDs []int64) error
- func (db *DB) MergeRepos(sourceRepoID, targetRepoID int64) (int64, error)
- func (db *DB) ReconcileBatch(batchID int64) (*CIPRBatch, error)
- func (db *DB) RecordBatchJob(batchID, jobID int64) error
- func (db *DB) RecordCIReview(githubRepo string, prNumber int, headSHA string, jobID int64) error
- func (db *DB) ReenqueueJob(jobID int64, opts ReenqueueOpts) error
- func (db *DB) RemapJob(repoID int64, oldSHA, newSHA, patchID string, author, subject string, ...) (int, error)
- func (db *DB) RemapJobGitRef(repoID int64, oldSHA, newSHA, patchID string, newCommitID int64) (int, error)
- func (db *DB) RenameRepo(identifier, newName string) (int64, error)
- func (db *DB) ResetStaleJobs() error
- func (db *DB) RetryJob(jobID int64, workerID string, maxRetries int) (bool, error)
- func (db *DB) SaveJobCommandLine(jobID int64, cmdLine string) error
- func (db *DB) SaveJobPatch(jobID int64, patch string) error
- func (db *DB) SaveJobPrompt(jobID int64, prompt string) error
- func (db *DB) SaveJobSessionID(jobID int64, workerID, sessionID string) error
- func (db *DB) SaveJobTokenUsage(jobID int64, tokenUsageJSON string) error
- func (db *DB) SetRepoIdentity(repoID int64, identity string) error
- func (db *DB) SetSyncState(key, value string) error
- func (db *DB) UnclaimBatch(batchID int64) error
- func (db *DB) UpdateJobBranch(jobID int64, branch string) (int64, error)
- func (db *DB) UpsertPulledJob(j PulledJob, repoID int64, commitID *int64) error
- func (db *DB) UpsertPulledResponse(r PulledResponse) error
- func (db *DB) UpsertPulledReview(r PulledReview) error
- type DaemonStatus
- type DurationStats
- type EnqueueOpts
- type ErrorEntry
- type FailureStats
- type HealthStatus
- type JobStats
- type JobStatus
- type JobTypeStats
- type JobWithPgIDs
- type JobWithReview
- type ListJobsOption
- func WithBeforeCursor(id int64) ListJobsOption
- func WithBranch(branch string) ListJobsOption
- func WithBranchOrEmpty(branch string) ListJobsOption
- func WithClosed(closed bool) ListJobsOption
- func WithExcludeJobType(jobType string) ListJobsOption
- func WithGitRef(ref string) ListJobsOption
- func WithJobType(jobType string) ListJobsOption
- func WithRepoPrefix(prefix string) ListJobsOption
- type ListReposOption
- type OverviewStats
- type PgPool
- func (p *PgPool) BatchInsertResponses(ctx context.Context, responses []SyncableResponse) ([]bool, error)
- func (p *PgPool) BatchUpsertJobs(ctx context.Context, jobs []JobWithPgIDs) ([]bool, error)
- func (p *PgPool) BatchUpsertReviews(ctx context.Context, reviews []SyncableReview) ([]bool, error)
- func (p *PgPool) Close()
- func (p *PgPool) EnsureSchema(ctx context.Context) error
- func (p *PgPool) GetDatabaseID(ctx context.Context) (string, error)
- func (p *PgPool) GetOrCreateCommit(ctx context.Context, repoID int64, sha, author, subject string, ...) (int64, error)
- func (p *PgPool) GetOrCreateRepo(ctx context.Context, identity string) (int64, error)
- func (p *PgPool) InsertResponse(ctx context.Context, r SyncableResponse) error
- func (p *PgPool) Ping(ctx context.Context) error
- func (p *PgPool) Pool() *pgxpool.Pool
- func (p *PgPool) PullJobs(ctx context.Context, excludeMachineID string, cursor string, limit int) ([]PulledJob, string, error)
- func (p *PgPool) PullResponses(ctx context.Context, excludeMachineID string, afterID int64, limit int) ([]PulledResponse, int64, error)
- func (p *PgPool) PullReviews(ctx context.Context, excludeMachineID string, knownJobUUIDs []string, ...) ([]PulledReview, string, error)
- func (p *PgPool) RegisterMachine(ctx context.Context, machineID, name string) error
- func (p *PgPool) Tx(ctx context.Context, fn func(tx pgx.Tx) error) error
- func (p *PgPool) UpsertJob(ctx context.Context, j SyncableJob, pgRepoID int64, pgCommitID *int64) error
- func (p *PgPool) UpsertReview(ctx context.Context, r SyncableReview) error
- type PgPoolConfig
- type PulledJob
- type PulledResponse
- type PulledReview
- type ReenqueueOpts
- type Repo
- type RepoStats
- type RepoSummary
- type RepoWithCount
- type Response
- type Review
- type ReviewJob
- type Summary
- type SummaryOptions
- type SyncProgress
- type SyncStats
- type SyncWorker
- func (w *SyncWorker) FinalPush() error
- func (w *SyncWorker) HealthCheck() (healthy bool, message string)
- func (w *SyncWorker) SetSkipInitialSync(skip bool) error
- func (w *SyncWorker) Start() error
- func (w *SyncWorker) Stop()
- func (w *SyncWorker) SyncNow() (*SyncStats, error)
- func (w *SyncWorker) SyncNowWithProgress(progressFn func(SyncProgress) bool) (*SyncStats, error)
- type SyncableJob
- type SyncableResponse
- type SyncableReview
- type VerdictStats
Constants ¶
const ( JobTypeReview = "review" // Single commit review JobTypeRange = "range" // Commit range review JobTypeDirty = "dirty" // Uncommitted changes review JobTypeTask = "task" // Run/analyze/design/custom prompt JobTypeInsights = "insights" // Historical review insights analysis JobTypeCompact = "compact" // Consolidated review verification JobTypeFix = "fix" // Background fix using worktree )
JobType classifies what kind of work a review job represents.
const ( SyncStateMachineID = "machine_id" SyncStateLastJobCursor = "last_job_cursor" // ID of last synced job SyncStateLastReviewCursor = "last_review_cursor" // Composite cursor for reviews (updated_at,id) SyncStateLastResponseID = "last_response_id" // ID of last synced response SyncStateSyncTargetID = "sync_target_id" // Database ID of last synced Postgres )
Sync state keys
Variables ¶
var ErrAmbiguousCommit = sql.ErrNoRows // Use sql.ErrNoRows for API compatibility; callers can check message
ErrAmbiguousCommit is returned when a SHA lookup matches multiple repos
var ErrRepoHasJobs = errors.New("repository has existing jobs; use cascade to delete them")
ErrRepoHasJobs is returned when trying to delete a repo with jobs without cascade
Functions ¶
func ExtractRepoNameFromIdentity ¶ added in v0.18.0
ExtractRepoNameFromIdentity extracts a human-readable name from a git identity. Examples:
- "git@github.com:org/repo.git" -> "repo"
- "https://github.com/org/my-project.git" -> "my-project"
- "https://github.com/org/repo" -> "repo"
- "" -> "unknown"
func GenerateUUID ¶
func GenerateUUID() string
GenerateUUID generates a random UUID v4 string. Uses crypto/rand for secure random generation.
func ParseVerdict ¶
ParseVerdict extracts P (pass) or F (fail) from review output. It intentionally uses a small set of deterministic signals: clear severity/findings markers mean fail, and clear pass phrases mean pass. We do not try to interpret narrative caveats after "No issues found." because that quickly turns into a brittle natural-language parser. If agent output is too chatty or mixes process narration with findings, that should be fixed in the review prompt rather than by adding more verdict heuristics here.
Types ¶
type AgentStats ¶ added in v0.47.0
type AgentStats struct {
Agent string `json:"agent"`
Total int `json:"total"`
Passed int `json:"passed"`
Failed int `json:"failed"`
Errors int `json:"errors"`
PassRate float64 `json:"pass_rate"`
MedianSecs float64 `json:"median_duration_secs"`
}
AgentStats contains per-agent performance metrics. Total counts all jobs by this agent (including task and fix jobs). Passed and Failed count only verdict-bearing review jobs, so Passed + Failed may be less than Total. PassRate is Passed/(Passed+Failed).
type BatchPRRef ¶ added in v0.40.0
BatchPRRef identifies a (github_repo, pr_number) pair for batch lookups.
type BatchReviewResult ¶ added in v0.26.0
type BatchReviewResult struct {
JobID int64 `json:"job_id"`
Agent string `json:"agent"`
ReviewType string `json:"review_type"`
Output string `json:"output"`
Status string `json:"status"` // "done" or "failed"
Error string `json:"error"`
}
BatchReviewResult holds the output of a single review job within a batch.
type BranchListResult ¶ added in v0.19.0
type BranchListResult struct {
Branches []BranchWithCount
TotalCount int
NullsRemaining int // Number of jobs with NULL/empty branch (for backfill tracking)
}
BranchListResult contains branches with counts and metadata
type BranchWithCount ¶ added in v0.19.0
BranchWithCount represents a branch with its total job count
type CIPRBatch ¶ added in v0.26.0
type CIPRBatch struct {
ID int64 `json:"id"`
GithubRepo string `json:"github_repo"`
PRNumber int `json:"pr_number"`
HeadSHA string `json:"head_sha"`
TotalJobs int `json:"total_jobs"`
CompletedJobs int `json:"completed_jobs"`
FailedJobs int `json:"failed_jobs"`
Synthesized bool `json:"synthesized"`
}
CIPRBatch tracks a batch of CI review jobs for a single PR at a specific HEAD SHA. A batch contains multiple jobs (review_types x agents matrix).
type CIPRReview ¶ added in v0.26.0
type CIPRReview struct {
ID int64 `json:"id"`
GithubRepo string `json:"github_repo"`
PRNumber int `json:"pr_number"`
HeadSHA string `json:"head_sha"`
JobID int64 `json:"job_id"`
}
CIPRReview tracks which PRs have been reviewed at which HEAD SHA
type ComponentHealth ¶
type ComponentHealth struct {
Name string `json:"name"`
Healthy bool `json:"healthy"`
Message string `json:"message,omitempty"`
}
ComponentHealth represents the health of a single component
type DB ¶
func (*DB) AddComment ¶ added in v0.17.0
AddComment adds a comment to a commit (legacy - use AddCommentToJob for new code)
func (*DB) AddCommentToJob ¶ added in v0.17.0
AddCommentToJob adds a comment linked to a job/review
func (*DB) BackfillRepoIdentities ¶
BackfillRepoIdentities computes and sets identity for repos that don't have one. Uses config.ResolveRepoIdentity to ensure consistency with new repo creation. Returns the number of repos backfilled.
func (*DB) BackfillSourceMachineID ¶
BackfillSourceMachineID sets source_machine_id on existing rows that don't have one. This should be called when sync is first enabled.
func (*DB) BackfillVerdictBool ¶ added in v0.47.0
BackfillVerdictBool populates verdict_bool for reviews that have output but a NULL verdict_bool. Returns the number of rows updated.
func (*DB) CancelClosedPRBatches ¶ added in v0.40.0
CancelClosedPRBatches cancels unclaimed pending batches (and their linked jobs) for a specific PR. Used when the PR is closed or merged. Skips batches that are currently claimed for synthesis to avoid racing with the posting flow. Returns the IDs of jobs that were canceled.
func (*DB) CancelJobWithError ¶ added in v0.50.0
CancelJobWithError cancels a queued or running job and sets an error message explaining why it was canceled. Returns sql.ErrNoRows if the job is already terminal.
func (*DB) CancelSupersededBatches ¶ added in v0.26.0
func (db *DB) CancelSupersededBatches(githubRepo string, prNumber int, newHeadSHA string) ([]int64, error)
CancelSupersededBatches cancels jobs and removes batches for a PR that have been superseded by a new HEAD SHA. Only affects unsynthesized batches (where the comment hasn't been posted yet). Returns the IDs of jobs that were canceled.
func (*DB) ClaimBatchForSynthesis ¶ added in v0.26.0
ClaimBatchForSynthesis atomically marks a batch as claimed only if it hasn't been claimed yet (CAS). Sets claimed_at so stale claims can be detected and recovered. Returns true if this caller won the claim.
func (*DB) ClearAllSyncedAt ¶
ClearAllSyncedAt clears all synced_at timestamps in the database. This is used when syncing to a new Postgres database to ensure all data gets re-synced.
func (*DB) CompleteFixJob ¶ added in v0.34.0
CompleteFixJob atomically marks a fix job as done, stores the review, and persists the patch in a single transaction. This prevents invalid states where a patch is written but the job isn't done, or vice versa.
func (*DB) CompleteJob ¶
CompleteJob marks a job as done and stores the review. Only updates if job is still in 'running' state (respects cancellation). If the job has an output_prefix, it will be prepended to the output.
func (*DB) CountBatchJobs ¶ added in v0.26.0
CountBatchJobs returns the number of jobs linked to a batch.
func (*DB) CountJobStats ¶ added in v0.28.0
func (db *DB) CountJobStats(repoFilter string, opts ...ListJobsOption) (JobStats, error)
CountJobStats returns aggregate done/closed/open counts using the same filter logic as ListJobs (repo, branch, closed).
func (*DB) CountStalledJobs ¶
CountStalledJobs returns the number of jobs that have been running longer than the threshold
func (*DB) CreateCIBatch ¶ added in v0.26.0
func (db *DB) CreateCIBatch(githubRepo string, prNumber int, headSHA string, totalJobs int) (*CIPRBatch, bool, error)
CreateCIBatch creates a new batch record for a PR. Uses INSERT OR IGNORE to handle races. Returns (batch, true) if this caller created the batch, or (batch, false) if the batch already existed (another poller won the race). Only the creator (created==true) should proceed to enqueue jobs.
func (*DB) DeleteCIBatch ¶ added in v0.26.0
DeleteCIBatch removes a batch and its job links. Used to clean up after a partial enqueue failure so the next poll can retry.
func (*DB) DeleteEmptyBatches ¶ added in v0.26.0
DeleteEmptyBatches removes batches with no linked jobs that are older than 1 minute. These are left behind when the daemon crashes between CreateCIBatch and RecordBatchJob. The age threshold avoids racing with in-progress enqueues.
func (*DB) DeleteRepo ¶
DeleteRepo deletes a repo and optionally its associated data If cascade is true, also deletes all jobs, reviews, and responses for the repo If cascade is false and jobs exist, returns ErrRepoHasJobs
func (*DB) EnqueueJob ¶
func (db *DB) EnqueueJob(opts EnqueueOpts) (*ReviewJob, error)
EnqueueJob creates a new review job. The job type is inferred from opts.
func (*DB) FailJob ¶
FailJob marks a job as failed with an error message. Only updates if job is still in 'running' state and owned by the given worker (respects cancellation and prevents stale workers from failing reclaimed jobs). Pass empty workerID to skip the ownership check (for admin/test callers). Returns true if the job was actually updated (false when ownership or status check prevented the update).
func (*DB) FailoverJob ¶ added in v0.33.0
FailoverJob atomically switches a running job to the given backup agent and requeues it. When backupModel is non-empty the job's model is set to that value; otherwise model is cleared (NULL) so the backup agent uses its CLI default. Returns false if the job is not in running state, the worker doesn't own the job, or the backup agent is the same as the current agent.
func (*DB) FinalizeBatch ¶ added in v0.26.0
FinalizeBatch clears claimed_at after a successful post. The batch stays synthesized=1 but with claimed_at=NULL, so GetStaleBatches won't re-pick it.
func (*DB) FindReusableSessionCandidate ¶ added in v0.45.0
func (db *DB) FindReusableSessionCandidate( repoID int64, branch, agent, reviewType, worktreePath string, ) (*ReviewJob, error)
FindReusableSessionCandidate returns the newest reusable session candidate.
func (*DB) FindReusableSessionCandidates ¶ added in v0.45.0
func (db *DB) FindReusableSessionCandidates( repoID int64, branch, agent, reviewType, worktreePath string, limit int, ) ([]ReviewJob, error)
FindReusableSessionCandidates returns recent completed jobs with reusable sessions for the same repo, branch, agent, and review type, newest first.
func (*DB) GetAllCommentsForJob ¶ added in v0.51.0
GetAllCommentsForJob returns all comments for a job, merging legacy commit-based comments via MergeResponses. When commitID > 0, fetches legacy comments by commit ID. Otherwise, if fallbackSHA is non-empty, fetches by SHA. Callers should validate the SHA (e.g. via git.LooksLikeSHA) before passing it here.
func (*DB) GetAllReviewsForGitRef ¶ added in v0.14.0
GetAllReviewsForGitRef returns all reviews for a git ref (commit SHA or range) for re-review context
func (*DB) GetBatchJobIDs ¶ added in v0.26.0
GetBatchJobIDs returns the review job IDs linked to a batch.
func (*DB) GetBatchReviews ¶ added in v0.26.0
func (db *DB) GetBatchReviews(batchID int64) ([]BatchReviewResult, error)
GetBatchReviews returns all review results for a batch by joining through ci_pr_batch_jobs.
func (*DB) GetCIBatchByJobID ¶ added in v0.26.0
GetCIBatchByJobID looks up the batch that contains a given job ID via ci_pr_batch_jobs.
func (*DB) GetCIReviewByJobID ¶ added in v0.26.0
func (db *DB) GetCIReviewByJobID(jobID int64) (*CIPRReview, error)
GetCIReviewByJobID returns the CI PR review for a given job ID, if any
func (*DB) GetCommentsForCommit ¶ added in v0.17.0
GetCommentsForCommit returns all comments for a commit
func (*DB) GetCommentsForCommitSHA ¶ added in v0.17.0
GetCommentsForCommitSHA returns all comments for a commit by SHA
func (*DB) GetCommentsForJob ¶ added in v0.17.0
GetCommentsForJob returns all comments linked to a job
func (*DB) GetCommentsToSync ¶ added in v0.17.0
func (db *DB) GetCommentsToSync(machineID string, limit int) ([]SyncableResponse, error)
GetCommentsToSync returns comments created locally that need to be pushed. Only returns comments whose parent job has already been synced.
func (*DB) GetCommitByID ¶
GetCommitByID returns a commit by its ID
func (*DB) GetCommitByRepoAndSHA ¶
GetCommitByRepoAndSHA returns a commit by repo ID and SHA
func (*DB) GetCommitBySHA ¶
GetCommitBySHA returns a commit by its SHA. DEPRECATED: This is a legacy API that doesn't handle the same SHA in different repos. Returns sql.ErrNoRows if no commit found, or if multiple repos have this SHA (ambiguous). Prefer using GetCommitByRepoAndSHA or job-based lookups instead.
func (*DB) GetExpiredBatches ¶ added in v0.50.0
GetExpiredBatches returns unsynthesized batches that have at least one done or failed job, at least one non-terminal job, and were created more than timeout ago. These batches should post early with available results. Only done/failed jobs qualify — user-canceled jobs are not meaningful results worth posting.
func (*DB) GetJobCounts ¶
func (db *DB) GetJobCounts() (queued, running, done, failed, canceled, applied, rebased int, err error)
GetJobCounts returns counts of jobs by status
func (*DB) GetJobRetryCount ¶
GetJobRetryCount returns the retry count for a job
func (*DB) GetJobsToSync ¶
func (db *DB) GetJobsToSync(machineID string, limit int) ([]SyncableJob, error)
GetJobsToSync returns terminal jobs that need to be pushed to PostgreSQL. These are jobs created locally that haven't been synced or were updated since last sync.
func (*DB) GetJobsWithReviewsByIDs ¶ added in v0.33.0
func (db *DB) GetJobsWithReviewsByIDs(jobIDs []int64) (map[int64]JobWithReview, error)
GetJobsWithReviewsByIDs fetches jobs and their reviews in batch for the given job IDs. Returns a map of job ID to JobWithReview. Jobs without reviews are included with a nil Review.
func (*DB) GetKnownJobUUIDs ¶
GetKnownJobUUIDs returns UUIDs of all jobs that have a UUID. Used to filter reviews when pulling from PostgreSQL.
func (*DB) GetMachineID ¶
GetMachineID returns this machine's unique identifier, creating one if it doesn't exist. Uses INSERT OR IGNORE + SELECT to ensure concurrency-safe behavior. Treats empty values as missing and regenerates.
func (*DB) GetNonTerminalBatchJobIDs ¶ added in v0.50.0
GetNonTerminalBatchJobIDs returns job IDs in a batch that are still queued or running (not done, failed, or canceled).
func (*DB) GetOrCreateCommit ¶
func (db *DB) GetOrCreateCommit(repoID int64, sha, author, subject string, timestamp time.Time) (*Commit, error)
GetOrCreateCommit finds or creates a commit record. Lookups are by (repo_id, sha) to handle the same SHA in different repos.
func (*DB) GetOrCreateCommitByRepoAndSHA ¶
func (db *DB) GetOrCreateCommitByRepoAndSHA(repoID int64, sha, author, subject string, timestamp time.Time) (int64, error)
GetOrCreateCommitByRepoAndSHA finds or creates a commit.
func (*DB) GetOrCreateRepo ¶
GetOrCreateRepo finds or creates a repo by its root path. If identity is provided, it will be stored; otherwise the identity field remains NULL.
func (*DB) GetOrCreateRepoByIdentity ¶
GetOrCreateRepoByIdentity finds or creates a repo for syncing by identity. The logic is:
- If exactly one local repo has this identity, use it (always preferred)
- If a placeholder repo exists (root_path == identity), use it
- If 0 or 2+ local repos have this identity, create a placeholder
This ensures synced jobs attach to the right repo:
- Single clone: jobs attach directly to the local repo
- Multiple clones: jobs attach to a neutral placeholder
- No local clone: placeholder serves as a sync-only repo
Note: Single local repos are always preferred, even if a placeholder exists from a previous sync (e.g., when there were 0 or 2+ clones before).
func (*DB) GetPendingBatchPRs ¶ added in v0.40.0
func (db *DB) GetPendingBatchPRs( githubRepo string, ) ([]BatchPRRef, error)
GetPendingBatchPRs returns the distinct (github_repo, pr_number) pairs that have unsynthesized, unclaimed batches. This lets the poller cross-reference pending batches against the open PR list without additional GitHub API calls.
func (*DB) GetRecentReviewsForRepo ¶
GetRecentReviewsForRepo returns the N most recent reviews for a repo
func (*DB) GetRepoByID ¶
GetRepoByID returns a repo by its ID
func (*DB) GetRepoByIdentity ¶
GetRepoByIdentity finds a repo by its identity. Returns nil if not found, error if duplicates exist.
func (*DB) GetRepoByIdentityCaseInsensitive ¶ added in v0.26.0
GetRepoByIdentityCaseInsensitive is like GetRepoByIdentity but uses case-insensitive comparison. Used by the CI poller since GitHub owner/repo names are case-insensitive. Excludes sync placeholders (root_path == identity) which don't have a real local checkout.
func (*DB) GetRepoByName ¶
GetRepoByName returns a repo by its display name
func (*DB) GetRepoByPath ¶
GetRepoByPath returns a repo by its path
func (*DB) GetRepoStats ¶
GetRepoStats returns detailed statistics for a repo
func (*DB) GetReviewByCommitSHA ¶
GetReviewByCommitSHA finds the most recent review by commit SHA (searches git_ref field)
func (*DB) GetReviewByID ¶
GetReviewByID finds a review by its ID
func (*DB) GetReviewByJobID ¶
GetReviewByJobID finds a review by its job ID
func (*DB) GetReviewsToSync ¶
func (db *DB) GetReviewsToSync(machineID string, limit int) ([]SyncableReview, error)
GetReviewsToSync returns reviews modified locally that need to be pushed. Only returns reviews whose parent job has already been synced.
func (*DB) GetStaleBatches ¶ added in v0.26.0
GetStaleBatches returns batches that need synthesis attention. This covers:
- Unclaimed batches where all jobs are terminal (dropped events, canceled jobs)
- Stale claims where the daemon crashed mid-post (claimed_at > 5 minutes ago)
func (*DB) GetSummary ¶ added in v0.47.0
func (db *DB) GetSummary(opts SummaryOptions) (*Summary, error)
GetSummary computes aggregate review statistics. All sub-queries run inside a single read transaction for snapshot consistency.
func (*DB) GetSyncState ¶
GetSyncState retrieves a value from the sync_state table. Returns empty string if key doesn't exist.
func (*DB) HasCIBatch ¶ added in v0.26.0
HasCIBatch checks if a batch already exists for this PR at this HEAD SHA. Only returns true if the batch has at least one linked job — an empty batch (from a crash between CreateCIBatch and RecordBatchJob) is treated as absent so the recovery path in processPR can clean it up.
func (*DB) HasCIReview ¶ added in v0.26.0
HasCIReview checks if a PR has already been reviewed at the given HEAD SHA
func (*DB) HasMeaningfulBatchResult ¶ added in v0.50.0
HasMeaningfulBatchResult reports whether a batch has at least one done or failed job (a result worth posting). User-canceled jobs without review output are excluded.
func (*DB) IncrementBatchCompleted ¶ added in v0.26.0
IncrementBatchCompleted atomically increments completed_jobs and returns the updated batch. The increment is conditional on synthesized=0 so late events arriving after the batch has been posted don't corrupt counters. Returns nil batch (no error) when the batch is already synthesized.
func (*DB) IncrementBatchFailed ¶ added in v0.26.0
IncrementBatchFailed atomically increments failed_jobs and returns the updated batch. The increment is conditional on synthesized=0 so late events arriving after the batch has been posted don't corrupt counters. Returns nil batch (no error) when the batch is already synthesized.
func (*DB) IsBatchExpired ¶ added in v0.50.0
IsBatchExpired reports whether a batch was created more than timeout ago. Used to check if a partially-complete batch should post early.
func (*DB) IsBatchStale ¶ added in v0.26.0
IsBatchStale reports whether a batch has had no activity for more than 1 minute. Staleness is based on updated_at (bumped by each RecordBatchJob) rather than created_at, so legitimately slow creators are not reclaimed while they are still making progress.
func (*DB) LatestBatchTimeForPR ¶ added in v0.40.0
LatestBatchTimeForPR returns the created_at timestamp of the most recent batch for the given PR, regardless of HEAD SHA. Returns zero time if no batch exists.
func (*DB) ListBranchesWithCounts ¶ added in v0.19.0
func (db *DB) ListBranchesWithCounts(repoPaths []string) (*BranchListResult, error)
ListBranchesWithCounts returns all branches with their job counts If repoPaths is non-empty, filters to jobs in those repos only
func (*DB) ListJobs ¶
func (db *DB) ListJobs(statusFilter string, repoFilter string, limit, offset int, opts ...ListJobsOption) ([]ReviewJob, error)
ListJobs returns jobs with optional status, repo, branch, and closed filters.
func (*DB) ListReposWithReviewCounts ¶
func (db *DB) ListReposWithReviewCounts(opts ...ListReposOption) ([]RepoWithCount, int, error)
ListReposWithReviewCounts returns repos with their total job counts. Options can filter by path prefix, branch, or both.
func (*DB) MarkCommentSynced ¶ added in v0.17.0
MarkCommentSynced updates the synced_at timestamp for a comment
func (*DB) MarkCommentsSynced ¶ added in v0.17.0
MarkCommentsSynced updates the synced_at timestamp for multiple comments
func (*DB) MarkJobApplied ¶ added in v0.34.0
MarkJobApplied transitions a fix job from done to applied.
func (*DB) MarkJobRebased ¶ added in v0.34.0
MarkJobRebased transitions a done fix job to the "rebased" terminal state. This indicates the patch was stale and a new rebase job was triggered.
func (*DB) MarkJobSynced ¶
MarkJobSynced updates the synced_at timestamp for a job
func (*DB) MarkJobsSynced ¶
MarkJobsSynced updates the synced_at timestamp for multiple jobs
func (*DB) MarkReviewClosed ¶ added in v0.40.0
MarkReviewClosed marks a review as closed (or reopened) by review ID
func (*DB) MarkReviewClosedByJobID ¶ added in v0.40.0
MarkReviewClosedByJobID marks a review as closed (or reopened) by job ID
func (*DB) MarkReviewSynced ¶
MarkReviewSynced updates the synced_at timestamp for a review
func (*DB) MarkReviewsSynced ¶
MarkReviewsSynced updates the synced_at timestamp for multiple reviews
func (*DB) MergeRepos ¶
MergeRepos moves all jobs and commits from sourceRepoID to targetRepoID, then deletes the source repo
func (*DB) ReconcileBatch ¶ added in v0.26.0
ReconcileBatch corrects the completed/failed counts for a batch by counting actual job statuses from the database.
func (*DB) RecordBatchJob ¶ added in v0.26.0
RecordBatchJob links a review job to a batch and bumps the batch's updated_at timestamp as a heartbeat so staleness detection is based on inactivity rather than age from creation.
func (*DB) RecordCIReview ¶ added in v0.26.0
RecordCIReview records that a PR was reviewed at a given HEAD SHA
func (*DB) ReenqueueJob ¶
func (db *DB) ReenqueueJob(jobID int64, opts ReenqueueOpts) error
ReenqueueJob resets a completed, failed, or canceled job back to queued status. This allows manual re-running of jobs to get a fresh review. For done jobs, the existing review is deleted to avoid unique constraint violations.
func (*DB) RemapJob ¶ added in v0.33.0
func (db *DB) RemapJob( repoID int64, oldSHA, newSHA, patchID string, author, subject string, timestamp time.Time, ) (int, error)
RemapJob atomically checks for matching jobs, creates the commit row, and updates git_ref — all in a single transaction to prevent orphan commit rows or races between concurrent remaps.
func (*DB) RemapJobGitRef ¶ added in v0.33.0
func (db *DB) RemapJobGitRef( repoID int64, oldSHA, newSHA, patchID string, newCommitID int64, ) (int, error)
RemapJobGitRef updates git_ref and commit_id for jobs matching oldSHA in a repo, used after rebases to preserve review history. If a job has a stored patch_id that differs from the provided one, that job is skipped (the commit's content changed). Returns the number of rows updated.
func (*DB) RenameRepo ¶
RenameRepo updates the display name of a repo identified by its path or current name
func (*DB) ResetStaleJobs ¶
ResetStaleJobs marks all running jobs as queued (for daemon restart)
func (*DB) RetryJob ¶
RetryJob requeues a running job for retry if retry_count < maxRetries. When workerID is non-empty the update is scoped to the owning worker, preventing a stale/zombie worker from requeuing a reclaimed job. Pass empty workerID to skip the ownership check (for admin/test callers).
func (*DB) SaveJobCommandLine ¶ added in v0.51.0
SaveJobCommandLine stores the actual agent command line used for this execution. Purely informational — reconstructed on each run.
func (*DB) SaveJobPatch ¶ added in v0.34.0
SaveJobPatch stores the generated patch for a completed fix job
func (*DB) SaveJobPrompt ¶
SaveJobPrompt stores the prompt for a running job
func (*DB) SaveJobSessionID ¶ added in v0.44.0
SaveJobSessionID stores the captured agent session ID for a job. The first captured ID wins so repeated lifecycle events do not overwrite it. The update is scoped to the current execution attempt: it requires status='running' and the given workerID so that a stale worker unwinding after cancel/retry cannot overwrite a session ID that belongs to a new attempt of the same job.
func (*DB) SaveJobTokenUsage ¶ added in v0.47.0
SaveJobTokenUsage stores a JSON blob of token consumption data.
func (*DB) SetRepoIdentity ¶
SetRepoIdentity sets the identity for a repo.
func (*DB) SetSyncState ¶
SetSyncState sets a value in the sync_state table (upsert).
func (*DB) UnclaimBatch ¶ added in v0.26.0
UnclaimBatch resets the synthesized flag so the reconciler can retry. Called when comment posting fails after a successful claim.
func (*DB) UpdateJobBranch ¶ added in v0.19.0
UpdateJobBranch sets the branch field for a job that doesn't have one. This is used to backfill the branch when it's derived from git. Only updates if the current branch is NULL or empty. Returns the number of rows affected (0 if branch was already set or job not found, 1 if updated).
func (*DB) UpsertPulledJob ¶
UpsertPulledJob inserts or updates a job from PostgreSQL into SQLite. Sets synced_at to prevent re-pushing. Requires repo to exist.
func (*DB) UpsertPulledResponse ¶
func (db *DB) UpsertPulledResponse(r PulledResponse) error
UpsertPulledResponse inserts a response from PostgreSQL into SQLite.
func (*DB) UpsertPulledReview ¶
func (db *DB) UpsertPulledReview(r PulledReview) error
UpsertPulledReview inserts or updates a review from PostgreSQL into SQLite.
type DaemonStatus ¶
type DaemonStatus struct {
Version string `json:"version"`
QueuedJobs int `json:"queued_jobs"`
RunningJobs int `json:"running_jobs"`
CompletedJobs int `json:"completed_jobs"`
FailedJobs int `json:"failed_jobs"`
CanceledJobs int `json:"canceled_jobs"`
AppliedJobs int `json:"applied_jobs"`
RebasedJobs int `json:"rebased_jobs"`
ActiveWorkers int `json:"active_workers"`
MaxWorkers int `json:"max_workers"`
MachineID string `json:"machine_id,omitempty"` // Local machine ID for remote job detection
ConfigReloadedAt string `json:"config_reloaded_at,omitempty"` // Last config reload timestamp (RFC3339Nano)
ConfigReloadCounter uint64 `json:"config_reload_counter,omitempty"` // Monotonic reload counter (for sub-second detection)
}
type DurationStats ¶ added in v0.47.0
type DurationStats struct {
ReviewP50 float64 `json:"review_p50_secs"`
ReviewP90 float64 `json:"review_p90_secs"`
ReviewP99 float64 `json:"review_p99_secs"`
QueueP50 float64 `json:"queue_p50_secs"`
QueueP90 float64 `json:"queue_p90_secs"`
QueueP99 float64 `json:"queue_p99_secs"`
}
DurationStats contains duration percentiles in seconds.
type EnqueueOpts ¶ added in v0.26.0
type EnqueueOpts struct {
RepoID int64
CommitID int64 // >0 for single-commit reviews
GitRef string // SHA, "start..end" range, or "dirty"
Branch string
SessionID string
Agent string
Model string // Effective model for this run
Provider string // Effective provider for this run (e.g. "anthropic", "openai")
RequestedModel string // Explicitly requested model; empty means reevaluate on rerun
RequestedProvider string // Explicitly requested provider; empty means reevaluate on rerun
Reasoning string
ReviewType string // e.g. "security" — changes which system prompt is used
PatchID string // Stable patch-id for rebase tracking
DiffContent string // For dirty reviews (captured at enqueue time)
Prompt string // For task jobs (pre-stored prompt)
OutputPrefix string // Prefix to prepend to review output
Agentic bool // Allow file edits and command execution
PromptPrebuilt bool // Prompt is prebuilt and should be used as-is by the worker
Label string // Display label in TUI for task jobs (default: "prompt")
JobType string // Explicit job type (review/range/dirty/task/compact/fix); inferred if empty
ParentJobID int64 // Parent job being fixed (for fix jobs)
WorktreePath string // Worktree checkout path (empty = use main repo root)
MinSeverity string // Minimum severity filter (canonical: critical/high/medium/low or empty)
}
EnqueueOpts contains options for creating any type of review job. The job type is inferred from which fields are set (in priority order):
- Prompt != "" → "task" (custom prompt job)
- DiffContent != "" → "dirty" (uncommitted changes)
- CommitID > 0 → "review" (single commit)
- otherwise → "range" (commit range)
type ErrorEntry ¶
type ErrorEntry struct {
Timestamp time.Time `json:"ts"`
Level string `json:"level"`
Component string `json:"component"`
Message string `json:"message"`
JobID int64 `json:"job_id,omitempty"`
}
ErrorEntry represents a single error log entry (mirrors daemon.ErrorEntry for API)
type FailureStats ¶ added in v0.47.0
type FailureStats struct {
Total int `json:"total"`
Retries int `json:"retries"`
Errors map[string]int `json:"errors"`
}
FailureStats contains failure categorization.
type HealthStatus ¶
type HealthStatus struct {
Healthy bool `json:"healthy"`
Uptime string `json:"uptime"`
Version string `json:"version"`
Components []ComponentHealth `json:"components"`
RecentErrors []ErrorEntry `json:"recent_errors"`
ErrorCount int `json:"error_count_24h"`
}
HealthStatus represents the overall daemon health
type JobStats ¶ added in v0.28.0
GetJobByID returns a job by ID with joined fields JobStats holds aggregate counts for the queue status line.
type JobTypeStats ¶ added in v0.47.0
type JobTypeStats struct {
Type string `json:"type"`
Count int `json:"count"`
Applied int `json:"applied,omitempty"`
Rebased int `json:"rebased,omitempty"`
}
JobTypeStats contains job counts by type with fix terminal status breakdown.
type JobWithPgIDs ¶
type JobWithPgIDs struct {
Job SyncableJob
PgRepoID int64
PgCommitID *int64
}
JobWithPgIDs represents a job with its resolved PostgreSQL repo and commit IDs
type JobWithReview ¶ added in v0.33.0
JobWithReview pairs a job with its review for batch operations
type ListJobsOption ¶ added in v0.21.0
type ListJobsOption func(*listJobsOptions)
ListJobsOption configures optional filters for ListJobs.
func WithBeforeCursor ¶ added in v0.51.0
func WithBeforeCursor(id int64) ListJobsOption
WithBeforeCursor filters jobs to those with ID < cursor (for cursor pagination).
func WithBranch ¶ added in v0.21.0
func WithBranch(branch string) ListJobsOption
WithBranch filters jobs by exact branch name.
func WithBranchOrEmpty ¶ added in v0.21.1
func WithBranchOrEmpty(branch string) ListJobsOption
WithBranchOrEmpty filters jobs by branch name, also including jobs with no branch set (empty string or NULL).
func WithClosed ¶ added in v0.40.0
func WithClosed(closed bool) ListJobsOption
WithClosed filters jobs by closed state (true/false).
func WithExcludeJobType ¶ added in v0.34.0
func WithExcludeJobType(jobType string) ListJobsOption
WithExcludeJobType excludes jobs of the given type.
func WithGitRef ¶ added in v0.21.0
func WithGitRef(ref string) ListJobsOption
WithGitRef filters jobs by git ref.
func WithJobType ¶ added in v0.34.0
func WithJobType(jobType string) ListJobsOption
WithJobType filters jobs by job_type (e.g. "fix", "review").
func WithRepoPrefix ¶ added in v0.42.0
func WithRepoPrefix(prefix string) ListJobsOption
WithRepoPrefix filters jobs to repos whose root_path starts with the given prefix.
type ListReposOption ¶ added in v0.42.0
type ListReposOption func(*listReposOptions)
ListReposOption configures filtering for ListReposWithReviewCounts.
func WithRepoBranch ¶ added in v0.42.0
func WithRepoBranch(branch string) ListReposOption
WithRepoBranch filters repos to those having jobs on the given branch. Use "(none)" to filter for jobs without a branch.
func WithRepoPathPrefix ¶ added in v0.42.0
func WithRepoPathPrefix(prefix string) ListReposOption
WithRepoPathPrefix filters repos whose root_path starts with the given prefix.
type OverviewStats ¶ added in v0.47.0
type OverviewStats struct {
Total int `json:"total"`
Queued int `json:"queued"`
Running int `json:"running"`
Done int `json:"done"`
Failed int `json:"failed"`
Canceled int `json:"canceled"`
Applied int `json:"applied"`
Rebased int `json:"rebased"`
}
OverviewStats contains job counts by status.
type PgPool ¶
type PgPool struct {
// contains filtered or unexported fields
}
PgPool wraps a pgx connection pool with reconnection logic
func NewPgPool ¶
NewPgPool creates a new PostgreSQL connection pool. The connection string should be a PostgreSQL URL like: postgres://user:pass@host:port/dbname?sslmode=disable
func (*PgPool) BatchInsertResponses ¶
func (p *PgPool) BatchInsertResponses(ctx context.Context, responses []SyncableResponse) ([]bool, error)
BatchInsertResponses inserts multiple responses in a single batch operation. Returns a boolean slice indicating success/failure for each item at the corresponding index.
func (*PgPool) BatchUpsertJobs ¶
BatchUpsertJobs inserts or updates multiple jobs in a single batch operation. The jobs must have their PgRepoID and PgCommitID already resolved. Returns a boolean slice indicating success/failure for each item at the corresponding index.
func (*PgPool) BatchUpsertReviews ¶
BatchUpsertReviews inserts or updates multiple reviews in a single batch operation. Returns a boolean slice indicating success/failure for each item at the corresponding index.
func (*PgPool) EnsureSchema ¶
EnsureSchema creates the schema if it doesn't exist and checks version. If legacy tables exist in the public schema, they are migrated to roborev.
func (*PgPool) GetDatabaseID ¶
GetDatabaseID returns the unique ID for this Postgres database. Creates one if it doesn't exist. This ID is used to detect when a client is syncing to a different database than before.
func (*PgPool) GetOrCreateCommit ¶
func (p *PgPool) GetOrCreateCommit(ctx context.Context, repoID int64, sha, author, subject string, timestamp time.Time) (int64, error)
GetOrCreateCommit finds or creates a commit, returns the PostgreSQL ID
func (*PgPool) GetOrCreateRepo ¶
GetOrCreateRepo finds or creates a repo by identity, returns the PostgreSQL ID
func (*PgPool) InsertResponse ¶
func (p *PgPool) InsertResponse(ctx context.Context, r SyncableResponse) error
InsertResponse inserts a response in PostgreSQL (append-only, no updates)
func (*PgPool) PullJobs ¶
func (p *PgPool) PullJobs(ctx context.Context, excludeMachineID string, cursor string, limit int) ([]PulledJob, string, error)
PullJobs fetches jobs from PostgreSQL updated after the given cursor. Cursor format: "updated_at id" (space-separated) or empty for first pull. Returns jobs not from the given machineID (to avoid echo).
func (*PgPool) PullResponses ¶
func (p *PgPool) PullResponses(ctx context.Context, excludeMachineID string, afterID int64, limit int) ([]PulledResponse, int64, error)
PullResponses fetches responses from PostgreSQL created after the given ID cursor.
func (*PgPool) PullReviews ¶
func (p *PgPool) PullReviews(ctx context.Context, excludeMachineID string, knownJobUUIDs []string, cursor string, limit int) ([]PulledReview, string, error)
PullReviews fetches reviews from PostgreSQL updated after the given cursor. Only fetches reviews for jobs in knownJobUUIDs to avoid cursor advancement past unknown jobs.
func (*PgPool) RegisterMachine ¶
RegisterMachine registers or updates this machine in the machines table
func (*PgPool) UpsertJob ¶
func (p *PgPool) UpsertJob(ctx context.Context, j SyncableJob, pgRepoID int64, pgCommitID *int64) error
UpsertJob inserts or updates a job in PostgreSQL
func (*PgPool) UpsertReview ¶
func (p *PgPool) UpsertReview(ctx context.Context, r SyncableReview) error
UpsertReview inserts or updates a review in PostgreSQL
type PgPoolConfig ¶
type PgPoolConfig struct {
// ConnectTimeout is the timeout for initial connection (default: 5s)
ConnectTimeout time.Duration
// MaxConns is the maximum number of connections (default: 4)
MaxConns int32
// MinConns is the minimum number of connections (default: 0)
MinConns int32
// MaxConnLifetime is the maximum lifetime of a connection (default: 1h)
MaxConnLifetime time.Duration
// MaxConnIdleTime is the maximum idle time before closing (default: 30m)
MaxConnIdleTime time.Duration
}
PgPoolConfig configures the PostgreSQL connection pool
func DefaultPgPoolConfig ¶
func DefaultPgPoolConfig() PgPoolConfig
DefaultPgPoolConfig returns sensible defaults for the connection pool
type PulledJob ¶
type PulledJob struct {
UUID string
RepoIdentity string
CommitSHA string
CommitAuthor string
CommitSubject string
CommitTimestamp time.Time
GitRef string
SessionID string
Agent string
Model string
Provider string
RequestedModel string
RequestedProvider string
Reasoning string
JobType string
ReviewType string
PatchID string
Status string
Agentic bool
EnqueuedAt time.Time
StartedAt *time.Time
FinishedAt *time.Time
Prompt string
DiffContent *string
Error string
TokenUsage string
WorktreePath string
MinSeverity string
SourceMachineID string
UpdatedAt time.Time
}
PulledJob represents a job pulled from PostgreSQL
type PulledResponse ¶
type PulledResponse struct {
UUID string
JobUUID string
Responder string
Response string
SourceMachineID string
CreatedAt time.Time
}
PulledResponse represents a response pulled from PostgreSQL
type PulledReview ¶
type PulledReview struct {
UUID string
JobUUID string
Agent string
Prompt string
Output string
Closed bool
UpdatedByMachineID string
CreatedAt time.Time
UpdatedAt time.Time
}
PulledReview represents a review pulled from PostgreSQL
type ReenqueueOpts ¶ added in v0.50.0
type Repo ¶
type Repo struct {
ID int64 `json:"id"`
RootPath string `json:"root_path"`
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
Identity string `json:"identity,omitempty"` // Unique identity for sync (git remote URL, .roborev-id, or local path)
}
func PreferAutoClone ¶ added in v0.51.0
PreferAutoClone picks the best repo from multiple matches. It prefers auto-clones (root_path under {DataDir}/clones/) since CI manages those and they won't have dirty working tree state. If no auto-clone is found, it returns the most recently created repo. Sync placeholders (root_path == identity) are skipped defensively.
type RepoStats ¶
type RepoStats struct {
Repo *Repo
TotalJobs int
QueuedJobs int
RunningJobs int
CompletedJobs int
FailedJobs int
PassedReviews int
FailedReviews int
ClosedReviews int
OpenReviews int
}
RepoStats contains statistics for a single repo
type RepoSummary ¶ added in v0.47.0
type RepoSummary struct {
Name string `json:"name"`
Path string `json:"path"`
Total int `json:"total"`
Passed int `json:"passed"`
Failed int `json:"failed"`
Addressed int `json:"addressed"`
}
RepoSummary contains per-repo summary when querying across all repos.
type RepoWithCount ¶
type RepoWithCount struct {
Name string `json:"name"`
RootPath string `json:"root_path"`
Count int `json:"count"`
}
RepoWithCount represents a repo with its total job count
type Response ¶
type Response struct {
ID int64 `json:"id"`
CommitID *int64 `json:"commit_id,omitempty"` // For commit-based responses (legacy)
JobID *int64 `json:"job_id,omitempty"` // For job/review-based responses
Responder string `json:"responder"`
Response string `json:"response"`
CreatedAt time.Time `json:"created_at"`
// Sync fields
UUID string `json:"uuid,omitempty"` // Globally unique identifier for sync
SourceMachineID string `json:"source_machine_id,omitempty"` // Machine that created this response
SyncedAt *time.Time `json:"synced_at,omitempty"` // Last sync time
}
func MergeResponses ¶ added in v0.51.0
MergeResponses deduplicates two Response slices by ID and returns a chronologically sorted result. This is used wherever job-based and legacy commit-based comments are merged.
type Review ¶
type Review struct {
ID int64 `json:"id"`
JobID int64 `json:"job_id"`
Agent string `json:"agent"`
Prompt string `json:"prompt"`
Output string `json:"output"`
CreatedAt time.Time `json:"created_at"`
Closed bool `json:"closed"`
// Sync fields
UUID string `json:"uuid,omitempty"` // Globally unique identifier for sync
UpdatedAt *time.Time `json:"updated_at,omitempty"` // Last modification time
UpdatedByMachineID string `json:"updated_by_machine_id,omitempty"` // Machine that last modified this review
SyncedAt *time.Time `json:"synced_at,omitempty"` // Last sync time
// Stored verdict: 1=pass, 0=fail, NULL=legacy (not yet backfilled)
VerdictBool *int `json:"verdict_bool,omitempty"`
// Joined fields
Job *ReviewJob `json:"job,omitempty"`
}
type ReviewJob ¶
type ReviewJob struct {
ID int64 `json:"id"`
RepoID int64 `json:"repo_id"`
CommitID *int64 `json:"commit_id,omitempty"` // nil for ranges
GitRef string `json:"git_ref"` // SHA or "start..end" for ranges
Branch string `json:"branch,omitempty"` // Branch name at time of job creation
SessionID string `json:"session_id,omitempty"` // Reused prior session or captured current session ID
Agent string `json:"agent"`
Model string `json:"model,omitempty"` // Effective model for this run (for opencode: provider/model format)
Provider string `json:"provider,omitempty"` // Effective provider for this run (e.g., anthropic, openai)
RequestedModel string `json:"requested_model,omitempty"` // Explicitly requested model; empty means reevaluate on rerun
RequestedProvider string `json:"requested_provider,omitempty"` // Explicitly requested provider; empty means reevaluate on rerun
Reasoning string `json:"reasoning,omitempty"` // thorough, standard, fast (default: thorough)
JobType string `json:"job_type"` // review, range, dirty, task, insights, compact, fix
Status JobStatus `json:"status"`
EnqueuedAt time.Time `json:"enqueued_at"`
StartedAt *time.Time `json:"started_at,omitempty"`
FinishedAt *time.Time `json:"finished_at,omitempty"`
WorkerID string `json:"worker_id,omitempty"`
Error string `json:"error,omitempty"`
Prompt string `json:"prompt,omitempty"`
RetryCount int `json:"retry_count"`
DiffContent *string `json:"diff_content,omitempty"` // For dirty reviews (uncommitted changes)
Agentic bool `json:"agentic"` // Enable agentic mode (allow file edits)
PromptPrebuilt bool `json:"prompt_prebuilt"` // Prompt was set at enqueue time and should be used as-is
ReviewType string `json:"review_type,omitempty"` // Review type (e.g., "security") - changes system prompt
PatchID string `json:"patch_id,omitempty"` // Stable patch-id for rebase tracking
OutputPrefix string `json:"output_prefix,omitempty"` // Prefix to prepend to review output
ParentJobID *int64 `json:"parent_job_id,omitempty"` // Job being fixed (for fix jobs)
Patch *string `json:"patch,omitempty"` // Generated diff patch (for completed fix jobs)
WorktreePath string `json:"worktree_path,omitempty"` // Worktree checkout path (empty = use RepoPath)
CommandLine string `json:"command_line,omitempty"` // Actual agent command line used for this run
MinSeverity string `json:"min_severity,omitempty"`
TokenUsage string `json:"token_usage,omitempty"` // JSON blob from agentsview (token consumption)
// Sync fields
UUID string `json:"uuid,omitempty"` // Globally unique identifier for sync
SourceMachineID string `json:"source_machine_id,omitempty"` // Machine that created this job
UpdatedAt *time.Time `json:"updated_at,omitempty"` // Last modification time
SyncedAt *time.Time `json:"synced_at,omitempty"` // Last sync time
// Joined fields for convenience
RepoPath string `json:"repo_path,omitempty"`
RepoName string `json:"repo_name,omitempty"`
CommitSubject string `json:"commit_subject,omitempty"` // empty for ranges
Closed *bool `json:"closed,omitempty"` // nil if no review yet
Verdict *string `json:"verdict,omitempty"` // P/F parsed from review output
}
func (ReviewJob) CommitIDValue ¶ added in v0.51.0
CommitIDValue returns the commit ID as a plain int64 (0 if nil).
func (ReviewJob) HasViewableOutput ¶ added in v0.34.0
HasViewableOutput returns true if this job has completed and its review/patch can be viewed. This covers done, applied, and rebased terminal states.
func (ReviewJob) IsDirtyJob ¶ added in v0.26.0
IsDirtyJob returns true if this is a dirty review (uncommitted changes).
func (ReviewJob) IsReviewJob ¶ added in v0.49.0
IsReviewJob returns true if this is an actual code review (single commit, range, or dirty) rather than a task, insights, compact, or fix job. The legacy fallback uses positive review signals (CommitID, dirty ref, range ref) to avoid misclassifying old stored-prompt jobs that happen to have a GitRef.
func (ReviewJob) IsTaskJob ¶ added in v0.20.0
IsTaskJob returns true if this is a task job (run, analyze, custom label) rather than a commit review or dirty review. Task jobs have pre-stored prompts and no verdicts. Compact jobs are not considered task jobs since they produce P/F verdicts.
func (ReviewJob) UsesStoredPrompt ¶ added in v0.34.0
UsesStoredPrompt returns true if this job type uses a pre-stored prompt (task, insights, compact, or fix). These job types have prompts built at enqueue time, not constructed by the worker from git data.
type Summary ¶ added in v0.47.0
type Summary struct {
Since time.Time `json:"since"`
RepoPath string `json:"repo_path,omitempty"`
Branch string `json:"branch,omitempty"`
Overview OverviewStats `json:"overview"`
Verdicts VerdictStats `json:"verdicts"`
Agents []AgentStats `json:"agents"`
Duration DurationStats `json:"duration"`
JobTypes []JobTypeStats `json:"job_types"`
Failures FailureStats `json:"failures"`
Repos []RepoSummary `json:"repos,omitempty"`
}
Summary holds aggregate review statistics for a time window.
type SummaryOptions ¶ added in v0.47.0
SummaryOptions configures the summary query.
type SyncProgress ¶
type SyncProgress struct {
Phase string // "push" or "pull"
BatchNum int
BatchJobs int
BatchRevs int
BatchResps int
TotalJobs int
TotalRevs int
TotalResps int
}
SyncProgress reports progress during a sync operation
type SyncStats ¶
type SyncStats struct {
PushedJobs int
PushedReviews int
PushedResponses int
PulledJobs int
PulledReviews int
PulledResponses int
}
SyncStats contains statistics from a sync operation
type SyncWorker ¶
type SyncWorker struct {
// contains filtered or unexported fields
}
SyncWorker handles background synchronization between SQLite and PostgreSQL
func NewSyncWorker ¶
func NewSyncWorker(db *DB, cfg config.SyncConfig) *SyncWorker
NewSyncWorker creates a new sync worker
func (*SyncWorker) FinalPush ¶
func (w *SyncWorker) FinalPush() error
FinalPush performs a push-only sync for graceful shutdown. This ensures all local changes are pushed before the daemon exits. Loops until all pending items are synced (not just one batch). Does not pull changes since we're shutting down.
func (*SyncWorker) HealthCheck ¶
func (w *SyncWorker) HealthCheck() (healthy bool, message string)
HealthCheck returns the health status of the sync worker
func (*SyncWorker) SetSkipInitialSync ¶ added in v0.33.1
func (w *SyncWorker) SetSkipInitialSync(skip bool) error
SetSkipInitialSync disables the immediate doSync that normally runs right after connecting. Must be called before Start().
func (*SyncWorker) Start ¶
func (w *SyncWorker) Start() error
Start begins the sync worker in a background goroutine. The worker can be stopped with Stop() and restarted with Start().
func (*SyncWorker) SyncNow ¶
func (w *SyncWorker) SyncNow() (*SyncStats, error)
SyncNow triggers an immediate sync cycle and returns statistics. Returns an error if the worker is not running or not connected. Loops until all pending items are pushed (not just one batch).
func (*SyncWorker) SyncNowWithProgress ¶
func (w *SyncWorker) SyncNowWithProgress(progressFn func(SyncProgress) bool) (*SyncStats, error)
SyncNowWithProgress is like SyncNow but calls progressFn after each batch. If not connected, attempts to connect first.
type SyncableJob ¶
type SyncableJob struct {
ID int64
UUID string
RepoID int64
RepoIdentity string
CommitID *int64
CommitSHA string
CommitAuthor string
CommitSubject string
CommitTimestamp time.Time
GitRef string
SessionID string
Agent string
Model string
Provider string
RequestedModel string
RequestedProvider string
Reasoning string
JobType string
ReviewType string
PatchID string
Status string
Agentic bool
EnqueuedAt time.Time
StartedAt *time.Time
FinishedAt *time.Time
Prompt string
DiffContent *string
Error string
TokenUsage string
WorktreePath string
MinSeverity string
SourceMachineID string
UpdatedAt time.Time
}
SyncableJob contains job data needed for sync
type SyncableResponse ¶
type SyncableResponse struct {
ID int64
UUID string
JobID int64
JobUUID string
Responder string
Response string
SourceMachineID string
CreatedAt time.Time
}
SyncableResponse contains response data needed for sync
type SyncableReview ¶
type SyncableReview struct {
ID int64
UUID string
JobID int64
JobUUID string
Agent string
Prompt string
Output string
Closed bool
UpdatedByMachineID string
CreatedAt time.Time
UpdatedAt time.Time
}
SyncableReview contains review data needed for sync
type VerdictStats ¶ added in v0.47.0
type VerdictStats struct {
Total int `json:"total"`
Passed int `json:"passed"`
Failed int `json:"failed"`
Addressed int `json:"addressed"`
PassRate float64 `json:"pass_rate"`
ResolutionRate float64 `json:"resolution_rate"`
}
VerdictStats contains pass/fail/addressed counts for completed reviews.