style: fix golines formatting for CI compliance
This commit is contained in:
parent
26da5defe8
commit
08e7bd5965
8 changed files with 175 additions and 33 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue