- Add Plane webhook handler for issue events (created, state, assignees) - Add Plane webhook integration tests with testdata fixtures - Add Gito Protosocket consumer wire readiness milestone - Add Plane work item webhook intake milestone - Add agent-task for plane-work-item-webhook-intake (trigger dispatch, idempotency, live smoke) - Update service config, router, handlers for Plane webhook endpoints - Add SOPS env setup script and secrets configuration - Update agent-ops domain rules and phase roadmap
124 lines
4.9 KiB
Go
124 lines
4.9 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
type Config struct {
|
|
AppEnv string
|
|
HTTPAddr string
|
|
DatabaseURL string
|
|
RedisURL string
|
|
RedisKeyPrefix string
|
|
AuthUsername string
|
|
AuthPassword string
|
|
ModelBaseURL string
|
|
ModelAPIKey string
|
|
ModelName string
|
|
ModelContextSize int
|
|
ModelTimeoutSec int
|
|
A2AEdgeURL string
|
|
A2AAgentURL string
|
|
A2AToken string
|
|
A2ATimeoutSec int
|
|
MattermostBaseURL string
|
|
MattermostToken string
|
|
MattermostChannelID string
|
|
PlaneBaseURL string
|
|
PlaneToken string
|
|
PlaneWebhookSecret string
|
|
JiraBaseURL string
|
|
JiraEmail string
|
|
JiraAPIToken string
|
|
WorkflowTaskTimeoutSec int
|
|
ProtoSocketPath string
|
|
ProtoSocketHeartbeatIntervalSec int
|
|
ProtoSocketHeartbeatWaitSec int
|
|
GitoProtoSocketURL string
|
|
GitoRepoID string
|
|
GitoBranch string
|
|
GitoDevelopRepoPath string
|
|
GitoRemoteName string
|
|
RoadmapCreationTodoStateID string
|
|
}
|
|
|
|
// GitoBranchEventsEnabled reports whether the Gito branch event consumer should
|
|
// run. It requires an endpoint, a repo id, a local develop checkout path to
|
|
// scan against, and a Todo state id to project into. Any missing piece keeps the
|
|
// consumer disabled so the rest of the Core server behaves exactly as before.
|
|
func (c Config) GitoBranchEventsEnabled() bool {
|
|
return c.GitoProtoSocketURL != "" &&
|
|
c.GitoRepoID != "" &&
|
|
c.GitoDevelopRepoPath != "" &&
|
|
c.RoadmapCreationTodoStateID != ""
|
|
}
|
|
|
|
func Load() Config {
|
|
return Config{
|
|
AppEnv: getEnv("APP_ENV", "local"),
|
|
HTTPAddr: getEnv("HTTP_ADDR", ":8080"),
|
|
DatabaseURL: os.Getenv("DATABASE_URL"),
|
|
RedisURL: os.Getenv("REDIS_URL"),
|
|
RedisKeyPrefix: os.Getenv("REDIS_KEY_PREFIX"),
|
|
AuthUsername: getEnv("AUTH_USERNAME", "nomadcode"),
|
|
AuthPassword: os.Getenv("AUTH_PASSWORD"),
|
|
ModelBaseURL: getEnv("MODEL_BASE_URL", "http://192.168.0.91:11434"),
|
|
ModelAPIKey: getEnv("MODEL_API_KEY", "ollama"),
|
|
ModelName: getEnv("MODEL_NAME", "qwen3.6:35b-a3b-bf16"),
|
|
ModelContextSize: getEnvInt("MODEL_CONTEXT_SIZE", 262144),
|
|
ModelTimeoutSec: getEnvInt("MODEL_TIMEOUT_SEC", 300),
|
|
A2AEdgeURL: firstEnv("A2A_EDGE_URL", "A2A_AGENT_URL"),
|
|
A2AAgentURL: firstEnv("A2A_AGENT_URL", "A2A_EDGE_URL"),
|
|
A2AToken: os.Getenv("A2A_TOKEN"),
|
|
A2ATimeoutSec: getEnvInt("A2A_TIMEOUT_SEC", 300),
|
|
MattermostBaseURL: os.Getenv("MATTERMOST_BASE_URL"),
|
|
MattermostToken: os.Getenv("MATTERMOST_TOKEN"),
|
|
MattermostChannelID: os.Getenv("MATTERMOST_CHANNEL_ID"),
|
|
PlaneBaseURL: os.Getenv("PLANE_BASE_URL"),
|
|
PlaneToken: os.Getenv("PLANE_TOKEN"),
|
|
PlaneWebhookSecret: os.Getenv("PLANE_WEBHOOK_SECRET"),
|
|
JiraBaseURL: os.Getenv("JIRA_BASE_URL"),
|
|
JiraEmail: os.Getenv("JIRA_EMAIL"),
|
|
JiraAPIToken: os.Getenv("JIRA_API_TOKEN"),
|
|
WorkflowTaskTimeoutSec: getEnvInt("WORKFLOW_TASK_TIMEOUT_SEC", 300),
|
|
ProtoSocketPath: getEnv("PROTO_SOCKET_PATH", "/proto-socket"),
|
|
ProtoSocketHeartbeatIntervalSec: getEnvInt("PROTO_SOCKET_HEARTBEAT_INTERVAL_SEC", 30),
|
|
ProtoSocketHeartbeatWaitSec: getEnvInt("PROTO_SOCKET_HEARTBEAT_WAIT_SEC", 10),
|
|
GitoProtoSocketURL: os.Getenv("GITO_PROTO_SOCKET_URL"),
|
|
GitoRepoID: os.Getenv("GITO_REPO_ID"),
|
|
GitoBranch: getEnv("GITO_BRANCH", "develop"),
|
|
GitoDevelopRepoPath: os.Getenv("GITO_DEVELOP_REPO_PATH"),
|
|
GitoRemoteName: getEnv("GITO_REMOTE_NAME", "origin"),
|
|
RoadmapCreationTodoStateID: firstEnv("ROADMAP_CREATION_TODO_STATE_ID", "PLANE_TODO_STATE_ID"),
|
|
}
|
|
}
|
|
|
|
func getEnv(key, fallback string) string {
|
|
value := os.Getenv(key)
|
|
if value == "" {
|
|
return fallback
|
|
}
|
|
return value
|
|
}
|
|
|
|
func firstEnv(keys ...string) string {
|
|
for _, key := range keys {
|
|
if value := os.Getenv(key); value != "" {
|
|
return value
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func getEnvInt(key string, fallback int) int {
|
|
value := os.Getenv(key)
|
|
if value == "" {
|
|
return fallback
|
|
}
|
|
parsed, err := strconv.Atoi(value)
|
|
if err != nil {
|
|
return fallback
|
|
}
|
|
return parsed
|
|
}
|