style: fix golines formatting for CI compliance

This commit is contained in:
Edouard CLAUDE 2026-02-21 16:00:33 +04:00
parent 26da5defe8
commit 08e7bd5965
8 changed files with 175 additions and 33 deletions

View file

@ -193,20 +193,32 @@ func gatewayCmd() {
cfg.Dashboard.Password = dashboard.GeneratePassword()
configPath := getConfigPath()
if saveErr := config.SaveConfig(configPath, cfg); saveErr != nil {
logger.ErrorCF("dashboard", "Failed to save generated password", map[string]any{"error": saveErr.Error()})
logger.ErrorCF(
"dashboard",
"Failed to save generated password",
map[string]any{"error": saveErr.Error()},
)
}
fmt.Printf("🔑 Dashboard password generated: %s\n", cfg.Dashboard.Password)
}
dashConfigPath := getConfigPath()
dashboard.Mount(healthServer, cfg, agentLoop, channelManager, dashConfigPath)
fmt.Printf("✓ Dashboard available at http://%s:%d/dashboard\n", cfg.Gateway.Host, cfg.Gateway.Port)
fmt.Printf(
"✓ Dashboard available at http://%s:%d/dashboard\n",
cfg.Gateway.Host,
cfg.Gateway.Port,
)
}
go func() {
if err := healthServer.Start(); err != nil && err != http.ErrServerClosed {
logger.ErrorCF("health", "Health server error", map[string]any{"error": err.Error()})
}
}()
fmt.Printf("✓ Health endpoints available at http://%s:%d/health and /ready\n", cfg.Gateway.Host, cfg.Gateway.Port)
fmt.Printf(
"✓ Health endpoints available at http://%s:%d/health and /ready\n",
cfg.Gateway.Host,
cfg.Gateway.Port,
)
go agentLoop.Run(ctx)
@ -239,7 +251,15 @@ func setupCronTool(
cronService := cron.NewCronService(cronStorePath, nil)
// Create and register CronTool
cronTool := tools.NewCronTool(cronService, agentLoop, msgBus, workspace, restrict, execTimeout, cfg)
cronTool := tools.NewCronTool(
cronService,
agentLoop,
msgBus,
workspace,
restrict,
execTimeout,
cfg,
)
agentLoop.RegisterTool(cronTool)
// Set the onJob handler

View file

@ -11,7 +11,12 @@ import (
"github.com/sipeed/picoclaw/pkg/config"
)
func statusHandler(cfg *config.Config, al *agent.AgentLoop, cm *channels.Manager, startTime time.Time) http.HandlerFunc {
func statusHandler(
cfg *config.Config,
al *agent.AgentLoop,
cm *channels.Manager,
startTime time.Time,
) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
info := al.GetStartupInfo()
channelStatus := cm.GetStatus()

View file

@ -13,7 +13,12 @@ import (
"github.com/sipeed/picoclaw/pkg/health"
)
func registerAgentsCRUD(srv *health.Server, cfg *config.Config, configPath string, auth func(http.HandlerFunc) http.HandlerFunc) {
func registerAgentsCRUD(
srv *health.Server,
cfg *config.Config,
configPath string,
auth func(http.HandlerFunc) http.HandlerFunc,
) {
srv.HandleFunc("/dashboard/fragments/agent-edit", auth(fragmentAgentEdit(cfg)))
srv.HandleFunc("/dashboard/fragments/agent-add", auth(fragmentAgentAdd()))
srv.HandleFunc("/dashboard/crud/agents/create", auth(agentCreateHandler(cfg, configPath)))
@ -256,7 +261,11 @@ func agentCreateHandler(cfg *config.Config, configPath string) http.HandlerFunc
if instructions := r.FormValue("instructions"); strings.TrimSpace(instructions) != "" {
ws := resolveAgentWorkspace(cfg, &agent)
if err := writeAgentInstructions(ws, instructions); err != nil {
jsonError(w, "agent created but failed to write AGENT.md: "+err.Error(), http.StatusInternalServerError)
jsonError(
w,
"agent created but failed to write AGENT.md: "+err.Error(),
http.StatusInternalServerError,
)
return
}
}
@ -318,7 +327,11 @@ func agentUpdateHandler(cfg *config.Config, configPath string) http.HandlerFunc
instructions := r.FormValue("instructions")
ws := resolveAgentWorkspace(cfg, found)
if err := writeAgentInstructions(ws, instructions); err != nil {
jsonError(w, "agent updated but failed to write AGENT.md: "+err.Error(), http.StatusInternalServerError)
jsonError(
w,
"agent updated but failed to write AGENT.md: "+err.Error(),
http.StatusInternalServerError,
)
return
}

View file

@ -11,7 +11,12 @@ import (
"github.com/sipeed/picoclaw/pkg/health"
)
func registerChannelsCRUD(srv *health.Server, cfg *config.Config, configPath string, auth func(http.HandlerFunc) http.HandlerFunc) {
func registerChannelsCRUD(
srv *health.Server,
cfg *config.Config,
configPath string,
auth func(http.HandlerFunc) http.HandlerFunc,
) {
srv.HandleFunc("/dashboard/fragments/channel-edit", auth(fragmentChannelEdit(cfg)))
srv.HandleFunc("/dashboard/crud/channels/update", auth(channelUpdateHandler(cfg, configPath)))
srv.HandleFunc("/dashboard/crud/channels/toggle", auth(channelToggleHandler(cfg, configPath)))
@ -100,7 +105,11 @@ func channelEditFormHTML(name string, cfg *config.Config) string {
allowFrom = ch.AllowFrom
fields = textField("ws_url", "WebSocket URL", ch.WSUrl) +
textField("access_token", "Access Token", ch.AccessToken) +
textField("reconnect_interval", "Reconnect Interval", strconv.Itoa(ch.ReconnectInterval))
textField(
"reconnect_interval",
"Reconnect Interval",
strconv.Itoa(ch.ReconnectInterval),
)
default:
return ""
}
@ -160,7 +169,11 @@ func fragmentChannelEdit(cfg *config.Config) http.HandlerFunc {
if html == "" {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, `<p class="error">Unknown channel: %s</p>`, template.HTMLEscapeString(name))
fmt.Fprintf(
w,
`<p class="error">Unknown channel: %s</p>`,
template.HTMLEscapeString(name),
)
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
@ -263,7 +276,11 @@ func channelUpdateHandler(cfg *config.Config, configPath string) http.HandlerFun
configMu.Unlock()
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, `<p class="error">Unknown channel: %s</p>`, template.HTMLEscapeString(name))
fmt.Fprintf(
w,
`<p class="error">Unknown channel: %s</p>`,
template.HTMLEscapeString(name),
)
return
}
configMu.Unlock()
@ -272,7 +289,11 @@ func channelUpdateHandler(cfg *config.Config, configPath string) http.HandlerFun
if err := saveConfig(configPath, cfg); err != nil {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, `<p class="error">Failed to save: %s</p>`, template.HTMLEscapeString(err.Error()))
fmt.Fprintf(
w,
`<p class="error">Failed to save: %s</p>`,
template.HTMLEscapeString(err.Error()),
)
return
}
}
@ -321,7 +342,11 @@ func channelToggleHandler(cfg *config.Config, configPath string) http.HandlerFun
configMu.Unlock()
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, `<p class="error">Unknown channel: %s</p>`, template.HTMLEscapeString(name))
fmt.Fprintf(
w,
`<p class="error">Unknown channel: %s</p>`,
template.HTMLEscapeString(name),
)
return
}
configMu.Unlock()
@ -330,7 +355,11 @@ func channelToggleHandler(cfg *config.Config, configPath string) http.HandlerFun
if err := saveConfig(configPath, cfg); err != nil {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, `<p class="error">Failed to save: %s</p>`, template.HTMLEscapeString(err.Error()))
fmt.Fprintf(
w,
`<p class="error">Failed to save: %s</p>`,
template.HTMLEscapeString(err.Error()),
)
return
}
}

View file

@ -10,7 +10,12 @@ import (
"github.com/sipeed/picoclaw/pkg/health"
)
func registerModelsCRUD(srv *health.Server, cfg *config.Config, configPath string, auth func(http.HandlerFunc) http.HandlerFunc) {
func registerModelsCRUD(
srv *health.Server,
cfg *config.Config,
configPath string,
auth func(http.HandlerFunc) http.HandlerFunc,
) {
srv.HandleFunc("/dashboard/fragments/model-edit", auth(fragmentModelEdit(cfg)))
srv.HandleFunc("/dashboard/fragments/model-add", auth(fragmentModelAdd()))
srv.HandleFunc("/dashboard/crud/models/create", auth(modelCreateHandler(cfg, configPath)))
@ -159,7 +164,11 @@ func modelCreateHandler(cfg *config.Config, configPath string) http.HandlerFunc
if err := saveConfig(configPath, cfg); err != nil {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, `<p class="error">Failed to save: %s</p>`, template.HTMLEscapeString(err.Error()))
fmt.Fprintf(
w,
`<p class="error">Failed to save: %s</p>`,
template.HTMLEscapeString(err.Error()),
)
return
}
}
@ -200,7 +209,11 @@ func modelUpdateHandler(cfg *config.Config, configPath string) http.HandlerFunc
if err := saveConfig(configPath, cfg); err != nil {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, `<p class="error">Failed to save: %s</p>`, template.HTMLEscapeString(err.Error()))
fmt.Fprintf(
w,
`<p class="error">Failed to save: %s</p>`,
template.HTMLEscapeString(err.Error()),
)
return
}
}
@ -237,7 +250,11 @@ func modelDeleteHandler(cfg *config.Config, configPath string) http.HandlerFunc
if err := saveConfig(configPath, cfg); err != nil {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, `<p class="error">Failed to save: %s</p>`, template.HTMLEscapeString(err.Error()))
fmt.Fprintf(
w,
`<p class="error">Failed to save: %s</p>`,
template.HTMLEscapeString(err.Error()),
)
return
}
}

View file

@ -10,11 +10,23 @@ import (
"github.com/sipeed/picoclaw/pkg/health"
)
func registerSettingsCRUD(srv *health.Server, cfg *config.Config, configPath string, currentPassword string, auth func(http.HandlerFunc) http.HandlerFunc) {
func registerSettingsCRUD(
srv *health.Server,
cfg *config.Config,
configPath string,
currentPassword string,
auth func(http.HandlerFunc) http.HandlerFunc,
) {
srv.HandleFunc("/dashboard/fragments/settings", auth(fragmentSettings(cfg, currentPassword)))
srv.HandleFunc("/dashboard/crud/settings/password", auth(passwordChangeHandler(cfg, configPath)))
srv.HandleFunc(
"/dashboard/crud/settings/password",
auth(passwordChangeHandler(cfg, configPath)),
)
srv.HandleFunc("/dashboard/crud/settings/gateway", auth(gatewayUpdateHandler(cfg, configPath)))
srv.HandleFunc("/dashboard/crud/settings/heartbeat", auth(heartbeatUpdateHandler(cfg, configPath)))
srv.HandleFunc(
"/dashboard/crud/settings/heartbeat",
auth(heartbeatUpdateHandler(cfg, configPath)),
)
srv.HandleFunc("/dashboard/crud/settings/devices", auth(devicesUpdateHandler(cfg, configPath)))
}

View file

@ -22,7 +22,11 @@ func TestPasswordChange(t *testing.T) {
form.Set("current_password", "oldpassword")
form.Set("new_password", "newpassword123")
req := httptest.NewRequest(http.MethodPost, "/dashboard/crud/settings/password", strings.NewReader(form.Encode()))
req := httptest.NewRequest(
http.MethodPost,
"/dashboard/crud/settings/password",
strings.NewReader(form.Encode()),
)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
w := httptest.NewRecorder()
@ -68,7 +72,11 @@ func TestPasswordChangeWrongCurrent(t *testing.T) {
form.Set("current_password", "wrongpassword")
form.Set("new_password", "newpassword123")
req := httptest.NewRequest(http.MethodPost, "/dashboard/crud/settings/password", strings.NewReader(form.Encode()))
req := httptest.NewRequest(
http.MethodPost,
"/dashboard/crud/settings/password",
strings.NewReader(form.Encode()),
)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
w := httptest.NewRecorder()
@ -99,7 +107,11 @@ func TestPasswordChangeTooShort(t *testing.T) {
form.Set("current_password", "oldpassword")
form.Set("new_password", "short")
req := httptest.NewRequest(http.MethodPost, "/dashboard/crud/settings/password", strings.NewReader(form.Encode()))
req := httptest.NewRequest(
http.MethodPost,
"/dashboard/crud/settings/password",
strings.NewReader(form.Encode()),
)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
w := httptest.NewRecorder()
@ -129,7 +141,11 @@ func TestGatewayUpdate(t *testing.T) {
form.Set("host", "127.0.0.1")
form.Set("port", "9090")
req := httptest.NewRequest(http.MethodPost, "/dashboard/crud/settings/gateway", strings.NewReader(form.Encode()))
req := httptest.NewRequest(
http.MethodPost,
"/dashboard/crud/settings/gateway",
strings.NewReader(form.Encode()),
)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
w := httptest.NewRecorder()
@ -174,7 +190,11 @@ func TestGatewayUpdateBadPort(t *testing.T) {
form.Set("host", "localhost")
form.Set("port", tt.port)
req := httptest.NewRequest(http.MethodPost, "/dashboard/crud/settings/gateway", strings.NewReader(form.Encode()))
req := httptest.NewRequest(
http.MethodPost,
"/dashboard/crud/settings/gateway",
strings.NewReader(form.Encode()),
)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
w := httptest.NewRecorder()
@ -197,7 +217,11 @@ func TestHeartbeatUpdate(t *testing.T) {
form.Set("enabled", "on")
form.Set("interval", "15")
req := httptest.NewRequest(http.MethodPost, "/dashboard/crud/settings/heartbeat", strings.NewReader(form.Encode()))
req := httptest.NewRequest(
http.MethodPost,
"/dashboard/crud/settings/heartbeat",
strings.NewReader(form.Encode()),
)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
w := httptest.NewRecorder()
@ -230,7 +254,11 @@ func TestDevicesUpdate(t *testing.T) {
form.Set("enabled", "on")
form.Set("monitor_usb", "on")
req := httptest.NewRequest(http.MethodPost, "/dashboard/crud/settings/devices", strings.NewReader(form.Encode()))
req := httptest.NewRequest(
http.MethodPost,
"/dashboard/crud/settings/devices",
strings.NewReader(form.Encode()),
)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
w := httptest.NewRecorder()

View file

@ -15,7 +15,13 @@ import (
"github.com/sipeed/picoclaw/pkg/logger"
)
func Mount(srv *health.Server, cfg *config.Config, al *agent.AgentLoop, cm *channels.Manager, configPath ...string) {
func Mount(
srv *health.Server,
cfg *config.Config,
al *agent.AgentLoop,
cm *channels.Manager,
configPath ...string,
) {
startTime := time.Now()
broker := NewBroker()
password := cfg.Dashboard.Password
@ -34,7 +40,10 @@ func Mount(srv *health.Server, cfg *config.Config, al *agent.AgentLoop, cm *chan
logger.ErrorCF("dashboard", "Failed to create sub FS", map[string]any{"error": err.Error()})
return
}
srv.Handle("/dashboard/static/", http.StripPrefix("/dashboard/static/", http.FileServer(http.FS(staticFS))))
srv.Handle(
"/dashboard/static/",
http.StripPrefix("/dashboard/static/", http.FileServer(http.FS(staticFS))),
)
// Auth routes (public)
srv.HandleFunc("/dashboard/login", func(w http.ResponseWriter, r *http.Request) {
@ -115,7 +124,12 @@ var funcMap = template.FuncMap{
"extractProvider": extractProvider,
}
func fragmentStatus(cfg *config.Config, al *agent.AgentLoop, cm *channels.Manager, startTime time.Time) http.HandlerFunc {
func fragmentStatus(
cfg *config.Config,
al *agent.AgentLoop,
cm *channels.Manager,
startTime time.Time,
) http.HandlerFunc {
const tmpl = `<div id="status-bar" class="status-bar">
<span class="indicator {{if .Running}}running{{else}}stopped{{end}}"></span>
<span>{{.Model}}</span>
@ -252,7 +266,11 @@ func fragmentAgentDetail(cfg *config.Config) http.HandlerFunc {
}
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintf(w, `<div><h3>Agent not found</h3><p>No agent with ID "%s"</p></div>`, template.HTMLEscapeString(agentID))
fmt.Fprintf(
w,
`<div><h3>Agent not found</h3><p>No agent with ID "%s"</p></div>`,
template.HTMLEscapeString(agentID),
)
}
}