Initial scaffold: API service, K8s operator, and CRDs

Forgebot is a K8s operator + API service for dispatching AI agent
jobs from git forge commands. Includes:

- CRDs: AgentPool, AgentTask, ProviderQueue, RepositoryBinding
- API server with webhook handler, task queue, and comment proxy
- Operator controllers for task scheduling and job management
- Gitea provider with webhook parsing and signature verification
- PostgreSQL database with auto-migration
- Woodpecker CI pipelines and multi-stage Dockerfiles
This commit is contained in:
2026-06-08 22:49:18 +10:00
parent fd1a4956ed
commit 49d514c050
46 changed files with 3139 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
package models
import "strings"
var ValidCommands = map[string]bool{
"plan": true,
"implement": true,
"review": true,
"test": true,
"fix": true,
"retry": true,
"cancel": true,
}
type ParsedCommand struct {
Name string
Args string
}
func ParseCommands(body string) []ParsedCommand {
var commands []ParsedCommand
for _, line := range strings.Split(body, "\n") {
line = strings.TrimSpace(line)
if !strings.HasPrefix(line, "/") {
continue
}
parts := strings.SplitN(line[1:], " ", 2)
name := strings.ToLower(parts[0])
if !ValidCommands[name] {
continue
}
cmd := ParsedCommand{Name: name}
if len(parts) > 1 {
cmd.Args = strings.TrimSpace(parts[1])
}
commands = append(commands, cmd)
}
return commands
}
+62
View File
@@ -0,0 +1,62 @@
package models
import "time"
type TaskStatus string
const (
StatusPending TaskStatus = "pending"
StatusRunning TaskStatus = "running"
StatusSucceeded TaskStatus = "succeeded"
StatusFailed TaskStatus = "failed"
StatusCancelled TaskStatus = "cancelled"
)
type Task struct {
ID string `json:"id"`
ParentTaskID string `json:"parentTaskId,omitempty"`
Command string `json:"command"`
Skill string `json:"skill,omitempty"`
Repository string `json:"repository"`
Ref string `json:"ref"`
IssueNumber int `json:"issueNumber,omitempty"`
PRNumber int `json:"prNumber,omitempty"`
CommentID int64 `json:"commentId,omitempty"`
Body string `json:"body,omitempty"`
Author string `json:"author"`
ExtraTools []string `json:"extraTools,omitempty"`
Status TaskStatus `json:"status"`
PoolRef string `json:"poolRef,omitempty"`
JobName string `json:"jobName,omitempty"`
Result string `json:"result,omitempty"`
ErrorMessage string `json:"errorMessage,omitempty"`
CreatedAt time.Time `json:"createdAt"`
StartedAt *time.Time `json:"startedAt,omitempty"`
CompletedAt *time.Time `json:"completedAt,omitempty"`
}
type CreateTaskRequest struct {
Command string `json:"command"`
Skill string `json:"skill,omitempty"`
Repository string `json:"repository"`
Ref string `json:"ref"`
IssueNumber int `json:"issueNumber,omitempty"`
PRNumber int `json:"prNumber,omitempty"`
CommentID int64 `json:"commentId,omitempty"`
Body string `json:"body,omitempty"`
Author string `json:"author"`
ExtraTools []string `json:"extraTools,omitempty"`
ParentTaskID string `json:"parentTaskId,omitempty"`
PoolRef string `json:"poolRef,omitempty"`
}
type UpdateTaskRequest struct {
Status TaskStatus `json:"status,omitempty"`
Message string `json:"message,omitempty"`
JobName string `json:"jobName,omitempty"`
ErrorMessage string `json:"errorMessage,omitempty"`
}
type CommentRequest struct {
Body string `json:"body"`
}