chore: initial commit (sources + docs, ignore build artifacts and secrets)

This commit is contained in:
toot
2026-09-16 12:24:49 +08:00
commit 8a6c55d94a
124 changed files with 12168 additions and 0 deletions
+280
View File
@@ -0,0 +1,280 @@
package main
import (
"context"
"os"
"path/filepath"
"MultiClawController/internal/controlplane"
)
// App is the deliberately narrow bridge between the Wails frontend and the control plane.
type App struct {
ctx context.Context
control *controlplane.ControlPlane
startErr error
}
func NewApp() *App { return &App{} }
func (a *App) startup(ctx context.Context) {
a.ctx = ctx
a.control, a.startErr = controlplane.Open(controllerConfigPath())
if a.startErr == nil {
a.startErr = a.control.StartAgentServer()
}
}
func (a *App) shutdown(context.Context) {
if a.control != nil {
a.control.Close()
}
}
// Snapshot returns dashboard data. It is safe to expose to the local WebView.
func (a *App) Snapshot() (controlplane.Snapshot, error) {
if a.startErr != nil {
return controlplane.Snapshot{}, a.startErr
}
return a.control.Snapshot()
}
// CreatePairingCode returns a short-lived secret. The frontend never persists it.
func (a *App) CreatePairingCode() (string, error) {
if a.startErr != nil {
return "", a.startErr
}
return a.control.CreatePairingCode()
}
func (a *App) OnlineAgents() ([]controlplane.Agent, error) {
if a.startErr != nil {
return nil, a.startErr
}
return a.control.OnlineAgents()
}
func (a *App) Agents() ([]controlplane.Agent, error) {
if a.startErr != nil {
return nil, a.startErr
}
return a.control.Agents()
}
// AgentDirectory is the paged, server-filtered Agent list for the management page.
func (a *App) AgentDirectory(filter controlplane.AgentDirectoryFilter) (controlplane.AgentDirectoryPage, error) {
if a.startErr != nil {
return controlplane.AgentDirectoryPage{}, a.startErr
}
return a.control.AgentDirectory(filter)
}
// AgentOperationalDetails returns bounded recent operational context for one Agent.
func (a *App) AgentOperationalDetails(agentID string) (controlplane.AgentOperationalDetail, error) {
if a.startErr != nil {
return controlplane.AgentOperationalDetail{}, a.startErr
}
return a.control.AgentOperationalDetails(agentID)
}
func (a *App) RenameAgent(agentID, name string) error {
if a.startErr != nil {
return a.startErr
}
return a.control.RenameAgent(agentID, name)
}
func (a *App) RevokeAgent(agentID string) error {
if a.startErr != nil {
return a.startErr
}
return a.control.RevokeAgent(agentID)
}
func (a *App) CreateTask(agentID, instruction string, timeoutSeconds int) (string, error) {
if a.startErr != nil {
return "", a.startErr
}
return a.control.CreateTask(agentID, instruction, timeoutSeconds)
}
func (a *App) CreateTaskWithImages(agentID, instruction string, timeoutSeconds int, images []controlplane.TaskImageInput) (string, error) {
if a.startErr != nil {
return "", a.startErr
}
return a.control.CreateTaskWithImages(agentID, instruction, timeoutSeconds, images)
}
// CreateTasks creates independently-addressed tasks from the multi-Agent task board.
func (a *App) CreateTasks(requests []controlplane.TaskRequest) ([]controlplane.TaskDispatchResult, error) {
if a.startErr != nil {
return nil, a.startErr
}
return a.control.CreateTasks(requests)
}
// DispatchMentions expands newline-separated public @AgentName assignments into
// independently addressed tasks.
func (a *App) DispatchMentions(message string, timeoutSeconds int) (controlplane.MentionDispatchResponse, error) {
if a.startErr != nil {
return controlplane.MentionDispatchResponse{}, a.startErr
}
return a.control.DispatchMentions(message, timeoutSeconds)
}
func (a *App) DispatchMentionsWithImages(message string, timeoutSeconds int, images []controlplane.TaskImageInput) (controlplane.MentionDispatchResponse, error) {
if a.startErr != nil {
return controlplane.MentionDispatchResponse{}, a.startErr
}
return a.control.DispatchMentionsWithImages(message, timeoutSeconds, images)
}
func (a *App) CancelTask(taskID string) error {
if a.startErr != nil {
return a.startErr
}
return a.control.CancelTask(taskID)
}
func (a *App) RetryTask(taskID string) (string, error) {
if a.startErr != nil {
return "", a.startErr
}
return a.control.RetryTask(taskID)
}
func (a *App) RecentTasks() ([]controlplane.Task, error) {
if a.startErr != nil {
return nil, a.startErr
}
return a.control.RecentTasks()
}
func (a *App) ClearTaskHistory() (int, error) {
if a.startErr != nil {
return 0, a.startErr
}
return a.control.ClearTaskHistory()
}
func (a *App) TaskDetails(taskID string) (controlplane.TaskDetail, error) {
if a.startErr != nil {
return controlplane.TaskDetail{}, a.startErr
}
return a.control.TaskDetails(taskID)
}
func (a *App) LLMProfiles() ([]controlplane.LLMProfile, error) {
if a.startErr != nil {
return nil, a.startErr
}
return a.control.LLMProfiles()
}
func (a *App) SaveLLMProfile(input controlplane.LLMProfileInput) (controlplane.LLMProfile, error) {
if a.startErr != nil {
return controlplane.LLMProfile{}, a.startErr
}
return a.control.SaveLLMProfile(input)
}
func (a *App) DeployLLMProfile(profileID string, agentIDs []string) error {
if a.startErr != nil {
return a.startErr
}
return a.control.DeployLLMProfile(profileID, agentIDs)
}
func (a *App) AgentLLMStatuses() ([]controlplane.AgentLLMStatus, error) {
if a.startErr != nil {
return nil, a.startErr
}
return a.control.AgentLLMStatuses()
}
func (a *App) Skills() ([]controlplane.Skill, error) {
if a.startErr != nil {
return nil, a.startErr
}
return a.control.Skills()
}
func (a *App) SkillDocument(skillID string) (controlplane.SkillDocument, error) {
if a.startErr != nil {
return controlplane.SkillDocument{}, a.startErr
}
return a.control.SkillDocument(skillID)
}
func (a *App) SaveSkill(input controlplane.SkillInput) (controlplane.Skill, error) {
if a.startErr != nil {
return controlplane.Skill{}, a.startErr
}
return a.control.SaveSkill(input)
}
func (a *App) DeploySkill(skillID string, agentIDs []string) error {
if a.startErr != nil {
return a.startErr
}
return a.control.DeploySkill(skillID, agentIDs)
}
func (a *App) SetAgentSkills(agentID string, skillIDs []string) error {
if a.startErr != nil {
return a.startErr
}
return a.control.SetAgentSkills(agentID, skillIDs)
}
func (a *App) AgentSkillStatuses() ([]controlplane.AgentSkillStatus, error) {
if a.startErr != nil {
return nil, a.startErr
}
return a.control.AgentSkillStatuses()
}
func (a *App) EnableDesktopFilesystem(agentIDs []string) error {
if a.startErr != nil {
return a.startErr
}
return a.control.EnableDesktopFilesystem(agentIDs)
}
func (a *App) AgentDeploymentStatuses() ([]controlplane.AgentDeploymentStatus, error) {
if a.startErr != nil {
return nil, a.startErr
}
return a.control.AgentDeploymentStatuses()
}
func (a *App) RecentAuditEvents() ([]controlplane.AuditEvent, error) {
if a.startErr != nil {
return nil, a.startErr
}
return a.control.RecentAuditEvents()
}
func (a *App) AuditTrail(filter controlplane.AuditFilter) (controlplane.AuditPage, error) {
if a.startErr != nil {
return controlplane.AuditPage{}, a.startErr
}
return a.control.AuditTrail(filter)
}
func controllerConfigPath() string {
if configured := os.Getenv("MULTICLAW_CONTROLLER_CONFIG_PATH"); configured != "" {
return configured
}
if executable, err := os.Executable(); err == nil {
candidate := filepath.Join(filepath.Dir(executable), "config", "controller-config.json")
if _, err := os.Stat(candidate); err == nil {
return candidate
}
}
workingDirectory, err := os.Getwd()
if err != nil {
return "config/controller-config.json"
}
return filepath.Join(workingDirectory, "config", "controller-config.json")
}