on main help sign in
chore: gofumpt project
commit45b1e634a5479297d94141ffc603a1d09f9b6326 authorChristian Rocha <christian@rocha.is> dateSat 16 May 2026, 08:56 (5 months ago) parented60003
46 files changed+194−104
internal/agent/agent.go+12−6 internal/agent/agent_tool.go+2−1 internal/agent/agentic_fetch_tool.go+4−2 internal/agent/coordinator.go+8−4 internal/agent/tools/bash.go+4−2 internal/agent/tools/crush_info.go+2−1 internal/agent/tools/diagnostics.go+2−1 internal/agent/tools/download.go+4−2 internal/agent/tools/edit.go+18−9 internal/agent/tools/fetch.go+4−2 internal/agent/tools/glob.go+2−1 internal/agent/tools/grep.go+2−1 internal/agent/tools/job_kill.go+2−1 internal/agent/tools/job_output.go+2−1 internal/agent/tools/list_mcp_resources.go+2−1 internal/agent/tools/ls.go+4−2 internal/agent/tools/lsp_restart.go+2−1 internal/agent/tools/mcp-tools.go+2−1 internal/agent/tools/multiedit.go+6−3 internal/agent/tools/read_mcp_resource.go+2−1 internal/agent/tools/references.go+2−1 internal/agent/tools/sourcegraph.go+2−1 internal/agent/tools/todos.go+2−1 internal/agent/tools/view.go+4−2 internal/agent/tools/web_fetch.go+2−1 internal/agent/tools/web_search.go+2−1 internal/agent/tools/write.go+6−3 internal/backend/backend.go+2−1 internal/cmd/root.go+2−1 internal/config/load_test.go+2−1 internal/event/event_test.go+2−1 internal/hooks/hooks.go+2−1 internal/hooks/hooks_test.go+6−3 internal/hooks/input.go+4−2 internal/hooks/runner.go+10−5 internal/proto/agent.go+2−2 internal/proto/mcp.go+4−4 internal/proto/proto.go+4−4 internal/server/logging.go+4−2 internal/shell/jq_test.go+2−1 internal/ui/chat/tools.go+10−7 internal/ui/dialog/commands.go+4−2 internal/ui/dialog/permissions.go+2−1 internal/ui/dialog/sessions_item.go+2−1 internal/ui/model/header.go+2−1 internal/ui/model/ui.go+22−11
internal/agent/agent.go+12−6
@@ -668,7 +668,8 @@ func (a *sessionAgent) Summarize(ctx context.Context, sessionID string, opts fan
668668 }
669669 }()
670670
671− agent := fantasy.NewAgent(largeModel.Model,
671+ agent := fantasy.NewAgent(
672+ largeModel.Model,
672673 fantasy.WithSystemPrompt(string(summaryPrompt)),
673674 fantasy.WithUserAgent(userAgent),
674675 )
@@ -814,7 +815,8 @@ func (a *sessionAgent) preparePrompt(msgs []message.Message, supportsImages bool
814815 var history []fantasy.Message
815816 if !a.isSubAgent {
816817 history = append(history, fantasy.NewUserMessage(
817− fmt.Sprintf("<system_reminder>%s</system_reminder>",
818+ fmt.Sprintf(
819+ "<system_reminder>%s</system_reminder>",
818820 `This is a reminder that your todo list is currently empty. DO NOT mention this to the user explicitly because they are already aware.
819821If you are working on tasks that would benefit from a todo list please use the "todos" tool to create one.
820822If not, please feel free to ignore. Again do not mention this message to the user.`,
@@ -920,7 +922,8 @@ func filterOrphanedToolResults(m message.Message, knownToolCallIDs map[string]st
920922 if _, known := knownToolCallIDs[tr.ToolCallID]; known {
921923 validParts = append(validParts, part)
922924 } else {
923− slog.Warn("Dropping orphaned tool result with no matching tool call",
925+ slog.Warn(
926+ "Dropping orphaned tool result with no matching tool call",
924927 "tool_call_id", tr.ToolCallID,
925928 )
926929 }
@@ -946,7 +949,8 @@ func syntheticToolResultsForOrphanedCalls(m message.Message, knownToolResultIDs
946949 if _, hasResult := knownToolResultIDs[tc.ID]; hasResult {
947950 continue
948951 }
949− slog.Warn("Injecting synthetic tool result for orphaned tool call",
952+ slog.Warn(
953+ "Injecting synthetic tool result for orphaned tool call",
950954 "tool_call_id", tc.ID,
951955 "tool_name", tc.Name,
952956 )
@@ -1004,7 +1008,8 @@ func (a *sessionAgent) generateTitle(ctx context.Context, sessionID string, user
10041008 }
10051009
10061010 newAgent := func(m fantasy.LanguageModel, p []byte, tok int64) fantasy.Agent {
1007− return fantasy.NewAgent(m,
1011+ return fantasy.NewAgent(
1012+ m,
10081013 fantasy.WithSystemPrompt(string(p)+"\n /no_think"),
10091014 fantasy.WithMaxOutputTokens(tok),
10101015 fantasy.WithUserAgent(userAgent),
@@ -1273,7 +1278,8 @@ func (a *sessionAgent) convertToToolResult(result fantasy.ToolResultContent) mes
12731278 case fantasy.ToolResultContentTypeMedia:
12741279 if r, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentMedia](result.Result); ok {
12751280 if !stringext.IsValidBase64(r.Data) {
1276− slog.Warn("Tool returned media with invalid base64 data, discarding image",
1281+ slog.Warn(
1282+ "Tool returned media with invalid base64 data, discarding image",
12771283 "tool", result.ToolName,
12781284 "tool_call_id", result.ToolCallID,
12791285 )
internal/agent/agent_tool.go+2−1
@@ -63,5 +63,6 @@ func (c *coordinator) agentTool(ctx context.Context) (fantasy.AgentTool, error)
6363 Prompt: params.Prompt,
6464 SessionTitle: "New Agent Session",
6565 })
66− }), nil
66+ },
67+ ), nil
6768}
internal/agent/agentic_fetch_tool.go+4−2
@@ -80,7 +80,8 @@ func (c *coordinator) agenticFetchTool(_ context.Context, client *http.Client) (
8080 description = "Search the web and analyze results"
8181 }
8282
83− p, err := c.permissions.Request(ctx,
83+ p, err := c.permissions.Request(
84+ ctx,
8485 permission.CreatePermissionRequest{
8586 SessionID: validationResult.SessionID,
8687 Path: c.cfg.WorkingDir(),
@@ -200,5 +201,6 @@ func (c *coordinator) agenticFetchTool(_ context.Context, client *http.Client) (
200201 c.permissions.AutoApproveSession(sessionID)
201202 },
202203 })
203− }), nil
204+ },
205+ ), nil
204206}
internal/agent/coordinator.go+8−4
@@ -491,7 +491,8 @@ func (c *coordinator) buildTools(ctx context.Context, agent config.Agent, isSubA
491491 hookRunner = hooks.NewRunner(preToolHooks, c.cfg.WorkingDir(), c.cfg.WorkingDir())
492492 }
493493
494− allTools = append(allTools,
494+ allTools = append(
495+ allTools,
495496 tools.NewBashTool(c.permissions, c.cfg.WorkingDir(), c.cfg.Config().Options.Attribution, modelID),
496497 tools.NewCrushInfoTool(c.cfg, c.lspManager, c.allSkills, c.activeSkills, c.skillTracker),
497498 tools.NewCrushLogsTool(logFile),
@@ -740,7 +741,8 @@ func (c *coordinator) buildOpenaiCompatProvider(baseURL, apiKey string, headers
740741 // Set HTTP client based on provider and debug mode.
741742 var httpClient *http.Client
742743 if providerID == string(catwalk.InferenceProviderCopilot) {
743− opts = append(opts,
744+ opts = append(
745+ opts,
744746 openaicompat.WithUseResponsesAPI(),
745747 openaicompat.WithResponsesAPIFunc(func(modelID string) bool {
746748 return copilotResponsesModels[modelID]
@@ -1213,7 +1215,8 @@ func logTurnSkillUsage(
12131215 }
12141216 }
12151217
1216− slog.Info("Skill turn summary",
1218+ slog.Info(
1219+ "Skill turn summary",
12171220 "component", "skills",
12181221 "session_id", sessionID,
12191222 "prompt_len", len(prompt),
@@ -1257,7 +1260,8 @@ func logDiscoveryStats(
12571260
12581261 xml := skills.ToPromptXML(activeSkills)
12591262
1260− slog.Info("Skill discovery complete",
1263+ slog.Info(
1264+ "Skill discovery complete",
12611265 "component", "skills",
12621266 "builtin_ok", len(builtin),
12631267 "builtin_errors", countErrors(builtinStates),
internal/agent/tools/bash.go+4−2
@@ -219,7 +219,8 @@ func NewBashTool(permissions permission.Service, workingDir string, attribution
219219 return fantasy.ToolResponse{}, fmt.Errorf("session ID is required for executing shell command")
220220 }
221221 if !isSafeReadOnly {
222− p, err := permissions.Request(ctx,
222+ p, err := permissions.Request(
223+ ctx,
223224 permission.CreatePermissionRequest{
224225 SessionID: sessionID,
225226 Path: execWorkingDir,
@@ -375,7 +376,8 @@ func NewBashTool(permissions permission.Service, workingDir string, attribution
375376 }
376377 response := fmt.Sprintf("Command is taking longer than expected and has been moved to background.\n\nBackground shell ID: %s\n\nUse job_output tool to view output or job_kill to terminate.", bgShell.ID)
377378 return fantasy.WithResponseMetadata(fantasy.NewTextResponse(response), metadata), nil
378− })
379+ },
380+ )
379381}
380382
381383// formatOutput formats the output of a completed command with error handling
internal/agent/tools/crush_info.go+2−1
@@ -33,7 +33,8 @@ func NewCrushInfoTool(
3333 crushInfoDescription,
3434 func(ctx context.Context, _ CrushInfoParams, _ fantasy.ToolCall) (fantasy.ToolResponse, error) {
3535 return fantasy.NewTextResponse(buildCrushInfo(cfg, lspManager, allSkills, activeSkills, skillTracker)), nil
36− })
36+ },
37+ )
3738}
3839
3940func buildCrushInfo(cfg *config.ConfigStore, lspManager *lsp.Manager, allSkills []*skills.Skill, activeSkills []*skills.Skill, skillTracker *skills.Tracker) string {
internal/agent/tools/diagnostics.go+2−1
@@ -35,7 +35,8 @@ func NewDiagnosticsTool(lspManager *lsp.Manager) fantasy.AgentTool {
3535 notifyLSPs(ctx, lspManager, params.FilePath)
3636 output := getDiagnostics(params.FilePath, lspManager)
3737 return fantasy.NewTextResponse(output), nil
38− })
38+ },
39+ )
3940}
4041
4142// openInLSPs ensures LSP servers are running and aware of the file, but does
internal/agent/tools/download.go+4−2
@@ -87,7 +87,8 @@ func NewDownloadTool(permissions permission.Service, workingDir string, client *
8787 return fantasy.ToolResponse{}, fmt.Errorf("session ID is required for downloading files")
8888 }
8989
90− p, err := permissions.Request(ctx,
90+ p, err := permissions.Request(
91+ ctx,
9192 permission.CreatePermissionRequest{
9293 SessionID: sessionID,
9394 Path: filePath,
@@ -160,5 +161,6 @@ func NewDownloadTool(permissions permission.Service, workingDir string, client *
160161 }
161162
162163 return fantasy.NewTextResponse(responseMsg), nil
163− })
164+ },
165+ )
164166}
internal/agent/tools/edit.go+18−9
@@ -104,7 +104,8 @@ func NewEditTool(
104104 text += getDiagnostics(params.FilePath, lspManager)
105105 response.Content = text
106106 return response, nil
107− })
107+ },
108+ )
108109}
109110
110111func createNewFile(edit editContext, filePath, content string, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
@@ -133,7 +134,8 @@ func createNewFile(edit editContext, filePath, content string, call fantasy.Tool
133134 content,
134135 strings.TrimPrefix(filePath, edit.workingDir),
135136 )
136− p, err := edit.permissions.Request(edit.ctx,
137+ p, err := edit.permissions.Request(
138+ edit.ctx,
137139 permission.CreatePermissionRequest{
138140 SessionID: sessionID,
139141 Path: fsext.PathOrPrefix(filePath, edit.workingDir),
@@ -213,9 +215,11 @@ func deleteContent(edit editContext, filePath, oldString string, replaceAll bool
213215 modTime := fileInfo.ModTime().Truncate(time.Second)
214216 if modTime.After(lastRead) {
215217 return fantasy.NewTextErrorResponse(
216− fmt.Sprintf("file %s has been modified since it was last read (mod time: %s, last read: %s)",
218+ fmt.Sprintf(
219+ "file %s has been modified since it was last read (mod time: %s, last read: %s)",
217220 filePath, modTime.Format(time.RFC3339), lastRead.Format(time.RFC3339),
218− )), nil
221+ ),
222+ ), nil
219223 }
220224
221225 content, err := os.ReadFile(filePath)
@@ -252,7 +256,8 @@ func deleteContent(edit editContext, filePath, oldString string, replaceAll bool
252256 strings.TrimPrefix(filePath, edit.workingDir),
253257 )
254258
255− p, err := edit.permissions.Request(edit.ctx,
259+ p, err := edit.permissions.Request(
260+ edit.ctx,
256261 permission.CreatePermissionRequest{
257262 SessionID: sessionID,
258263 Path: fsext.PathOrPrefix(filePath, edit.workingDir),
@@ -344,9 +349,11 @@ func replaceContent(edit editContext, filePath, oldString, newString string, rep
344349 modTime := fileInfo.ModTime().Truncate(time.Second)
345350 if modTime.After(lastRead) {
346351 return fantasy.NewTextErrorResponse(
347− fmt.Sprintf("file %s has been modified since it was last read (mod time: %s, last read: %s)",
352+ fmt.Sprintf(
353+ "file %s has been modified since it was last read (mod time: %s, last read: %s)",
348354 filePath, modTime.Format(time.RFC3339), lastRead.Format(time.RFC3339),
349− )), nil
355+ ),
356+ ), nil
350357 }
351358
352359 content, err := os.ReadFile(filePath)
@@ -383,7 +390,8 @@ func replaceContent(edit editContext, filePath, oldString, newString string, rep
383390 strings.TrimPrefix(filePath, edit.workingDir),
384391 )
385392
386− p, err := edit.permissions.Request(edit.ctx,
393+ p, err := edit.permissions.Request(
394+ edit.ctx,
387395 permission.CreatePermissionRequest{
388396 SessionID: sessionID,
389397 Path: fsext.PathOrPrefix(filePath, edit.workingDir),
@@ -445,5 +453,6 @@ func replaceContent(edit editContext, filePath, oldString, newString string, rep
445453 NewContent: newContent,
446454 Additions: additions,
447455 Removals: removals,
448− }), nil
456+ },
457+ ), nil
449458}
internal/agent/tools/fetch.go+4−2
@@ -77,7 +77,8 @@ func NewFetchTool(permissions permission.Service, workingDir string, client *htt
7777 return fantasy.ToolResponse{}, fmt.Errorf("session ID is required for creating a new file")
7878 }
7979
80− p, err := permissions.Request(ctx,
80+ p, err := permissions.Request(
81+ ctx,
8182 permission.CreatePermissionRequest{
8283 SessionID: sessionID,
8384 Path: workingDir,
@@ -184,7 +185,8 @@ func NewFetchTool(permissions permission.Service, workingDir string, client *htt
184185 }
185186
186187 return fantasy.NewTextResponse(content), nil
187− })
188+ },
189+ )
188190}
189191
190192func extractTextFromHTML(html string) (string, error) {
internal/agent/tools/glob.go+2−1
@@ -82,7 +82,8 @@ func NewGlobTool(workingDir string) fantasy.AgentTool {
8282 Truncated: truncated,
8383 },
8484 ), nil
85− })
85+ },
86+ )
8687}
8788
8889func globFiles(ctx context.Context, pattern, searchPath string, limit int) ([]string, bool, error) {
internal/agent/tools/grep.go+2−1
@@ -186,7 +186,8 @@ func NewGrepTool(workingDir string, config config.ToolGrep) fantasy.AgentTool {
186186 Truncated: truncated,
187187 },
188188 ), nil
189− })
189+ },
190+ )
190191}
191192
192193func searchFiles(ctx context.Context, pattern, rootPath, include string, limit int) ([]grepMatch, bool, error) {
internal/agent/tools/job_kill.go+2−1
@@ -55,5 +55,6 @@ func NewJobKillTool() fantasy.AgentTool {
5555
5656 result := fmt.Sprintf("Background shell %s terminated successfully", params.ShellID)
5757 return fantasy.WithResponseMetadata(fantasy.NewTextResponse(result), metadata), nil
58− })
58+ },
59+ )
5960}
internal/agent/tools/job_output.go+2−1
@@ -87,5 +87,6 @@ func NewJobOutputTool() fantasy.AgentTool {
8787
8888 result := fmt.Sprintf("Status: %s\n\n%s", status, output)
8989 return fantasy.WithResponseMetadata(fantasy.NewTextResponse(result), metadata), nil
90− })
90+ },
91+ )
9192}
internal/agent/tools/list_mcp_resources.go+2−1
@@ -44,7 +44,8 @@ func NewListMCPResourcesTool(cfg *config.ConfigStore, permissions permission.Ser
4444 }
4545
4646 relPath := filepathext.SmartJoin(cfg.WorkingDir(), params.MCPName)
47− p, err := permissions.Request(ctx,
47+ p, err := permissions.Request(
48+ ctx,
4849 permission.CreatePermissionRequest{
4950 SessionID: sessionID,
5051 Path: relPath,
internal/agent/tools/ls.go+4−2
@@ -102,7 +102,8 @@ func NewLsTool(permissions permission.Service, workingDir string, lsConfig confi
102102 return fantasy.ToolResponse{}, fmt.Errorf("session ID is required for accessing directories outside working directory")
103103 }
104104
105− granted, err := permissions.Request(ctx,
105+ granted, err := permissions.Request(
106+ ctx,
106107 permission.CreatePermissionRequest{
107108 SessionID: sessionID,
108109 Path: absSearchPath,
@@ -130,7 +131,8 @@ func NewLsTool(permissions permission.Service, workingDir string, lsConfig confi
130131 fantasy.NewTextResponse(output),
131132 metadata,
132133 ), nil
133− })
134+ },
135+ )
134136}
135137
136138func ListDirectoryTree(searchPath string, params LSParams, lsConfig config.ToolLs) (string, LSResponseMetadata, error) {
internal/agent/tools/lsp_restart.go+2−1
@@ -75,5 +75,6 @@ func NewLSPRestartTool(lspManager *lsp.Manager) fantasy.AgentTool {
7575 }
7676
7777 return fantasy.NewTextResponse(output), nil
78− })
78+ },
79+ )
7980}
internal/agent/tools/mcp-tools.go+2−1
@@ -105,7 +105,8 @@ func (m *Tool) Run(ctx context.Context, params fantasy.ToolCall) (fantasy.ToolRe
105105 // Skip permission for whitelisted Docker MCP tools.
106106 if !slices.Contains(whitelistDockerTools, params.Name) {
107107 permissionDescription := fmt.Sprintf("execute %s with the following parameters:", m.Info().Name)
108− p, err := m.permissions.Request(ctx,
108+ p, err := m.permissions.Request(
109+ ctx,
109110 permission.CreatePermissionRequest{
110111 SessionID: sessionID,
111112 ToolCallID: params.ID,
internal/agent/tools/multiedit.go+6−3
@@ -110,7 +110,8 @@ func NewMultiEditTool(
110110 text += getDiagnostics(params.FilePath, lspManager)
111111 response.Content = text
112112 return response, nil
113− })
113+ },
114+ )
114115}
115116
116117func validateEdits(edits []MultiEditOperation) error {
@@ -266,9 +267,11 @@ func processMultiEditExistingFile(edit editContext, params MultiEditParams, call
266267 modTime := fileInfo.ModTime().Truncate(time.Second)
267268 if modTime.After(lastRead) {
268269 return fantasy.NewTextErrorResponse(
269− fmt.Sprintf("file %s has been modified since it was last read (mod time: %s, last read: %s)",
270+ fmt.Sprintf(
271+ "file %s has been modified since it was last read (mod time: %s, last read: %s)",
270272 params.FilePath, modTime.Format(time.RFC3339), lastRead.Format(time.RFC3339),
271− )), nil
273+ ),
274+ ), nil
272275 }
273276
274277 // Read current file content
internal/agent/tools/read_mcp_resource.go+2−1
@@ -50,7 +50,8 @@ func NewReadMCPResourceTool(cfg *config.ConfigStore, permissions permission.Serv
5050 }
5151
5252 relPath := filepathext.SmartJoin(cfg.WorkingDir(), cmp.Or(params.URI, "mcp-resource"))
53− p, err := permissions.Request(ctx,
53+ p, err := permissions.Request(
54+ ctx,
5455 permission.CreatePermissionRequest{
5556 SessionID: sessionID,
5657 Path: relPath,
internal/agent/tools/references.go+2−1
@@ -87,7 +87,8 @@ func NewReferencesTool(lspManager *lsp.Manager) fantasy.AgentTool {
8787 return fantasy.NewTextErrorResponse(allErrs.Error()), nil
8888 }
8989 return fantasy.NewTextResponse(fmt.Sprintf("No references found for symbol '%s'", params.Symbol)), nil
90− })
90+ },
91+ )
9192}
9293
9394func (r *referencesTool) Name() string {
internal/agent/tools/sourcegraph.go+2−1
@@ -150,7 +150,8 @@ func NewSourcegraphTool(client *http.Client) fantasy.AgentTool {
150150 }
151151
152152 return fantasy.NewTextResponse(formattedResults), nil
153− })
153+ },
154+ )
154155}
155156
156157func formatSourcegraphResults(result map[string]any, contextWindow int) (string, error) {
internal/agent/tools/todos.go+2−1
@@ -130,5 +130,6 @@ func NewTodosTool(sessions session.Service) fantasy.AgentTool {
130130 }
131131
132132 return fantasy.WithResponseMetadata(fantasy.NewTextResponse(response), metadata), nil
133− })
133+ },
134+ )
134135}
internal/agent/tools/view.go+4−2
@@ -134,7 +134,8 @@ func NewViewTool(
134134
135135 // Request permission for files outside working directory, unless it's a skill file.
136136 if isOutsideWorkDir && !isSkillFile {
137− granted, permReqErr := permissions.Request(ctx,
137+ granted, permReqErr := permissions.Request(
138+ ctx,
138139 permission.CreatePermissionRequest{
139140 SessionID: sessionID,
140141 Path: absFilePath,
@@ -274,7 +275,8 @@ func NewViewTool(
274275 fantasy.NewTextResponse(output),
275276 meta,
276277 ), nil
277− })
278+ },
279+ )
278280}
279281
280282func addLineNumbers(content string, startLine int) string {
internal/agent/tools/web_fetch.go+2−1
@@ -75,5 +75,6 @@ func NewWebFetchTool(workingDir string, client *http.Client) fantasy.AgentTool {
7575 }
7676
7777 return fantasy.NewTextResponse(result.String()), nil
78− })
78+ },
79+ )
7980}
internal/agent/tools/web_search.go+2−1
@@ -57,5 +57,6 @@ func NewWebSearchTool(client *http.Client) fantasy.AgentTool {
5757 }
5858
5959 return fantasy.NewTextResponse(formatSearchResults(results)), nil
60− })
60+ },
61+ )
6162}
internal/agent/tools/write.go+6−3
@@ -105,7 +105,8 @@ func NewWriteTool(
105105 strings.TrimPrefix(filePath, workingDir),
106106 )
107107
108− p, err := permissions.Request(ctx,
108+ p, err := permissions.Request(
109+ ctx,
109110 permission.CreatePermissionRequest{
110111 SessionID: sessionID,
111112 Path: fsext.PathOrPrefix(filePath, workingDir),
@@ -161,12 +162,14 @@ func NewWriteTool(
161162 result := fmt.Sprintf("File successfully written: %s", filePath)
162163 result = fmt.Sprintf("<result>\n%s\n</result>", result)
163164 result += getDiagnostics(filePath, lspManager)
164− return fantasy.WithResponseMetadata(fantasy.NewTextResponse(result),
165+ return fantasy.WithResponseMetadata(
166+ fantasy.NewTextResponse(result),
165167 WriteResponseMetadata{
166168 Diff: diff,
167169 Additions: additions,
168170 Removals: removals,
169171 },
170172 ), nil
171− })
173+ },
174+ )
172175}
internal/backend/backend.go+2−1
@@ -122,7 +122,8 @@ func (b *Backend) CreateWorkspace(args proto.Workspace) (*Workspace, proto.Works
122122 b.workspaces.Set(id, ws)
123123
124124 if args.Version != "" && args.Version != version.Version {
125− slog.Warn("Client/server version mismatch",
125+ slog.Warn(
126+ "Client/server version mismatch",
126127 "client", args.Version,
127128 "server", version.Version,
128129 )
internal/cmd/root.go+2−1
@@ -486,7 +486,8 @@ func perHostServerDir(hostURL *url.URL) (string, error) {
486486// the --host flag so client and server compute the same key.
487487func safeHostName(hostURL *url.URL) string {
488488 return safeNameRegexp.ReplaceAllString(
489− hostURL.Scheme+"://"+hostURL.Host+hostURL.Path, "_")
489+ hostURL.Scheme+"://"+hostURL.Host+hostURL.Path, "_",
490+ )
490491}
491492
492493// serverReadyTimeout returns the total budget for the readiness probe.
internal/config/load_test.go+2−1
@@ -248,7 +248,8 @@ func TestConfig_setDefaults(t *testing.T) {
248248 cfg := &Config{}
249249 cfg.setDefaults(child, "")
250250
251− require.Equal(t,
251+ require.Equal(
252+ t,
252253 filepath.Clean(filepath.Join(child, defaultDataDirectory)),
253254 filepath.Clean(cfg.Options.DataDirectory),
254255 )
internal/event/event_test.go+2−1
@@ -54,7 +54,8 @@ func TestError(t *testing.T) {
5454 }()
5555
5656 client = nil
57− Error("test error",
57+ Error(
58+ "test error",
5859 "type", "test",
5960 "severity", "high",
6061 "source", "unit-test",
internal/hooks/hooks.go+2−1
@@ -128,7 +128,8 @@ func aggregate(results []HookResult, origToolInput string) AggregateResult {
128128 if r.UpdatedInput != "" {
129129 next, err := shallowMerge(merged, r.UpdatedInput)
130130 if err != nil {
131− slog.Warn("Hook updated_input patch rejected; ignoring",
131+ slog.Warn(
132+ "Hook updated_input patch rejected; ignoring",
132133 "error", err,
133134 "patch", r.UpdatedInput,
134135 )
internal/hooks/hooks_test.go+6−3
@@ -538,7 +538,8 @@ func TestAggregationUpdatedInput(t *testing.T) {
538538 require.Equal(t, DecisionAllow, agg.Decision)
539539 // command overridden by second patch; keep preserved from first
540540 // patch; timeout preserved from original input.
541− require.JSONEq(t,
541+ require.JSONEq(
542+ t,
542543 `{"command":"second","keep":"me","timeout":60}`,
543544 agg.UpdatedInput,
544545 )
@@ -550,7 +551,8 @@ func TestAggregationUpdatedInput(t *testing.T) {
550551 {Decision: DecisionAllow, UpdatedInput: `{"env":{"FOO":"bar"}}`},
551552 }, `{"env":{"BAZ":"qux"},"command":"ls"}`)
552553 // "env" is replaced entirely; "command" preserved.
553− require.JSONEq(t,
554+ require.JSONEq(
555+ t,
554556 `{"env":{"FOO":"bar"},"command":"ls"}`,
555557 agg.UpdatedInput,
556558 )
@@ -678,7 +680,8 @@ func TestRunnerUpdatedInput(t *testing.T) {
678680 result, err := r.Run(context.Background(), EventPreToolUse, "sess", "bash", `{"command":"echo original","timeout":60}`)
679681 require.NoError(t, err)
680682 require.Equal(t, DecisionAllow, result.Decision)
681− require.JSONEq(t,
683+ require.JSONEq(
684+ t,
682685 `{"command":"echo rewritten","timeout":60}`,
683686 result.UpdatedInput,
684687 )
internal/hooks/input.go+4−2
@@ -53,7 +53,8 @@ func BuildPayload(eventName, sessionID, cwd, toolName, toolInputJSON string) []b
5353func BuildEnv(eventName, toolName, sessionID, cwd, projectDir, toolInputJSON string) []string {
5454 env := os.Environ()
5555 env = append(env, shell.CrushEnvMarkers()...)
56− env = append(env,
56+ env = append(
57+ env,
5758 fmt.Sprintf("CRUSH_EVENT=%s", eventName),
5859 fmt.Sprintf("CRUSH_TOOL_NAME=%s", toolName),
5960 fmt.Sprintf("CRUSH_SESSION_ID=%s", sessionID),
@@ -105,7 +106,8 @@ func parseStdout(stdout string) HookResult {
105106 }
106107
107108 if parsed.Version > SupportedOutputVersion {
108− slog.Debug("Hook output declared a newer envelope version than this build supports",
109+ slog.Debug(
110+ "Hook output declared a newer envelope version than this build supports",
109111 "version", parsed.Version,
110112 "supported", SupportedOutputVersion,
111113 )
internal/hooks/runner.go+10−5
@@ -54,7 +54,8 @@ func NewRunner(hooks []config.HookConfig, cwd, projectDir string) *Runner {
5454 if h.Matcher != "" {
5555 re, err := regexp.Compile(h.Matcher)
5656 if err != nil {
57− slog.Warn("Hook matcher failed to compile; skipping hook",
57+ slog.Warn(
58+ "Hook matcher failed to compile; skipping hook",
5859 "matcher", h.Matcher,
5960 "command", h.Command,
6061 "error", err,
@@ -130,7 +131,8 @@ func (r *Runner) Run(ctx context.Context, eventName, sessionID, toolName, toolIn
130131 InputRewrite: results[i].UpdatedInput != "",
131132 }
132133 }
133− slog.Info("Hook completed",
134+ slog.Info(
135+ "Hook completed",
134136 "event", eventName,
135137 "tool", toolName,
136138 "hooks", len(deduped),
@@ -194,7 +196,8 @@ func (r *Runner) runOne(parentCtx context.Context, hook config.HookConfig, envVa
194196 case err = <-done:
195197 // Interpreter yielded within the grace period; safe to read.
196198 case <-time.After(abandonGrace):
197− slog.Warn("Hook did not yield after cancel; abandoning goroutine",
199+ slog.Warn(
200+ "Hook did not yield after cancel; abandoning goroutine",
198201 "command", hook.Command,
199202 "timeout", timeout,
200203 )
@@ -240,7 +243,8 @@ func (r *Runner) runOne(parentCtx context.Context, hook config.HookConfig, envVa
240243 }
241244 default:
242245 // Other non-zero exits are non-blocking errors.
243− slog.Warn("Hook failed with non-blocking error",
246+ slog.Warn(
247+ "Hook failed with non-blocking error",
244248 "command", hook.Command,
245249 "exit_code", exitCode,
246250 "stderr", strings.TrimSpace(stderr.String()),
@@ -252,7 +256,8 @@ func (r *Runner) runOne(parentCtx context.Context, hook config.HookConfig, envVa
252256
253257 // Exit code 0 — parse stdout JSON.
254258 result := parseStdout(stdout.String())
255− slog.Debug("Hook executed",
259+ slog.Debug(
260+ "Hook executed",
256261 "command", hook.Command,
257262 "decision", result.Decision.String(),
258263 )
internal/proto/agent.go+2−2
@@ -51,7 +51,7 @@ func (e AgentEvent) MarshalJSON() ([]byte, error) {
5151 }
5252 return ""
5353 }(),
54− Alias: (Alias)(e),
54+ Alias: Alias(e),
5555 })
5656}
5757
@@ -62,7 +62,7 @@ func (e *AgentEvent) UnmarshalJSON(data []byte) error {
6262 Error string `json:"error,omitempty"`
6363 Alias
6464 }{
65− Alias: (Alias)(*e),
65+ Alias: Alias(*e),
6666 }
6767 if err := json.Unmarshal(data, &aux); err != nil {
6868 return err
internal/proto/mcp.go+4−4
@@ -100,7 +100,7 @@ func (e MCPEvent) MarshalJSON() ([]byte, error) {
100100 }
101101 return ""
102102 }(),
103− Alias: (Alias)(e),
103+ Alias: Alias(e),
104104 })
105105}
106106
@@ -111,7 +111,7 @@ func (e *MCPEvent) UnmarshalJSON(data []byte) error {
111111 Error string `json:"error,omitempty"`
112112 Alias
113113 }{
114− Alias: (Alias)(*e),
114+ Alias: Alias(*e),
115115 }
116116 if err := json.Unmarshal(data, &aux); err != nil {
117117 return err
@@ -148,7 +148,7 @@ func (i MCPClientInfo) MarshalJSON() ([]byte, error) {
148148 }
149149 return ""
150150 }(),
151− Alias: (Alias)(i),
151+ Alias: Alias(i),
152152 })
153153}
154154
@@ -159,7 +159,7 @@ func (i *MCPClientInfo) UnmarshalJSON(data []byte) error {
159159 Error string `json:"error,omitempty"`
160160 Alias
161161 }{
162− Alias: (Alias)(*i),
162+ Alias: Alias(*i),
163163 }
164164 if err := json.Unmarshal(data, &aux); err != nil {
165165 return err
internal/proto/proto.go+4−4
@@ -131,7 +131,7 @@ func (e LSPEvent) MarshalJSON() ([]byte, error) {
131131 }
132132 return ""
133133 }(),
134− Alias: (Alias)(e),
134+ Alias: Alias(e),
135135 })
136136}
137137
@@ -142,7 +142,7 @@ func (e *LSPEvent) UnmarshalJSON(data []byte) error {
142142 Error string `json:"error,omitempty"`
143143 Alias
144144 }{
145− Alias: (Alias)(*e),
145+ Alias: Alias(*e),
146146 }
147147 if err := json.Unmarshal(data, &aux); err != nil {
148148 return err
@@ -176,7 +176,7 @@ func (i LSPClientInfo) MarshalJSON() ([]byte, error) {
176176 }
177177 return ""
178178 }(),
179− Alias: (Alias)(i),
179+ Alias: Alias(i),
180180 })
181181}
182182
@@ -187,7 +187,7 @@ func (i *LSPClientInfo) UnmarshalJSON(data []byte) error {
187187 Error string `json:"error,omitempty"`
188188 Alias
189189 }{
190− Alias: (Alias)(*i),
190+ Alias: Alias(*i),
191191 }
192192 if err := json.Unmarshal(data, &aux); err != nil {
193193 return err
internal/server/logging.go+4−2
@@ -15,7 +15,8 @@ func (s *Server) loggingHandler(next http.Handler) http.Handler {
1515
1616 start := time.Now()
1717 lrw := &loggingResponseWriter{ResponseWriter: w, statusCode: http.StatusOK}
18− s.logger.Debug("HTTP request",
18+ s.logger.Debug(
19+ "HTTP request",
1920 slog.String("method", r.Method),
2021 slog.String("path", r.URL.Path),
2122 slog.String("remote_addr", r.RemoteAddr),
@@ -25,7 +26,8 @@ func (s *Server) loggingHandler(next http.Handler) http.Handler {
2526 next.ServeHTTP(lrw, r)
2627 duration := time.Since(start)
2728
28− s.logger.Debug("HTTP response",
29+ s.logger.Debug(
30+ "HTTP response",
2931 slog.String("method", r.Method),
3032 slog.String("path", r.URL.Path),
3133 slog.Int("status", lrw.statusCode),
internal/shell/jq_test.go+2−1
@@ -185,7 +185,8 @@ func TestJQ_Success(t *testing.T) {
185185 t.Parallel()
186186
187187 var stdout bytes.Buffer
188− err := handleJQ(t.Context(),
188+ err := handleJQ(
189+ t.Context(),
189190 []string{"jq", "-c", ".a"},
190191 strings.NewReader(`{"a":1}`),
191192 &stdout, io.Discard,
internal/ui/chat/tools.go+10−7
@@ -690,9 +690,10 @@ func toolOutputCodeContent(sty *styles.Styles, path, content string, offset, wid
690690
691691 // Add truncation message if needed.
692692 if len(lines) > maxLines && !expanded {
693− out = append(out, sty.Tool.ContentCodeTruncation.
694− Width(width).
695− Render(fmt.Sprintf(assistantMessageTruncateFormat, len(lines)-maxLines)),
693+ out = append(
694+ out, sty.Tool.ContentCodeTruncation.
695+ Width(width).
696+ Render(fmt.Sprintf(assistantMessageTruncateFormat, len(lines)-maxLines)),
696697 )
697698 }
698699
@@ -851,7 +852,8 @@ func renderHookLine(sty *styles.Styles, hi hooks.HookInfo, rawName, detail strin
851852 arrowStyle = sty.Tool.HookDeniedLabel
852853 }
853854
854− return fmt.Sprintf("%s %s%s%s %s %s",
855+ return fmt.Sprintf(
856+ "%s %s%s%s %s %s",
855857 labelStyle.Render("Hook"),
856858 name,
857859 namePad,
@@ -1063,9 +1065,10 @@ func toolOutputMarkdownContent(sty *styles.Styles, content string, width int, ex
10631065 }
10641066
10651067 if len(lines) > maxLines && !expanded {
1066− out = append(out, sty.Tool.ContentTruncation.
1067− Width(width).
1068− Render(fmt.Sprintf(assistantMessageTruncateFormat, len(lines)-maxLines)),
1068+ out = append(
1069+ out, sty.Tool.ContentTruncation.
1070+ Width(width).
1071+ Render(fmt.Sprintf(assistantMessageTruncateFormat, len(lines)-maxLines)),
10691072 )
10701073 }
10711074
internal/ui/dialog/commands.go+4−2
@@ -510,7 +510,8 @@ func (c *Commands) defaultCommands() []*CommandItem {
510510 }
511511 commands = append(commands, NewCommandItem(c.com.Styles, "toggle_notifications", notificationLabel, "", ActionToggleNotifications{}))
512512
513− commands = append(commands,
513+ commands = append(
514+ commands,
514515 NewCommandItem(c.com.Styles, "toggle_yolo", "Toggle Yolo Mode", "", ActionToggleYoloMode{}),
515516 NewCommandItem(c.com.Styles, "toggle_help", "Toggle Help", "ctrl+g", ActionToggleHelp{}),
516517 NewCommandItem(c.com.Styles, "init", "Initialize Project", "", ActionInitializeProject{}),
@@ -523,7 +524,8 @@ func (c *Commands) defaultCommands() []*CommandItem {
523524 }
524525 commands = append(commands, NewCommandItem(c.com.Styles, "toggle_transparent", transparentLabel, "", ActionToggleTransparentBackground{}))
525526
526− commands = append(commands,
527+ commands = append(
528+ commands,
527529 NewCommandItem(c.com.Styles, "quit", "Quit", "ctrl+c", tea.QuitMsg{}).WithAliases("exit"),
528530 )
529531
internal/ui/dialog/permissions.go+2−1
@@ -775,7 +775,8 @@ func (p *Permissions) ShortHelp() []key.Binding {
775775 }
776776
777777 if p.hasDiffView() {
778− bindings = append(bindings,
778+ bindings = append(
779+ bindings,
779780 p.keyMap.ToggleDiffMode,
780781 p.keyMap.ToggleFullscreen,
781782 )
internal/ui/dialog/sessions_item.go+2−1
@@ -184,7 +184,8 @@ func renderItem(t ListItemStyles, title string, info string, focused bool, width
184184 // precisely via [ansi.AttrUnderline] and [ansi.AttrNoUnderline]
185185 // which only affect the underline attribute without interfering
186186 // with other style attributes.
187− parts = append(parts,
187+ parts = append(
188+ parts,
188189 ansi.NewStyle().Underline(true).String(),
189190 ansi.Cut(title, start, stop+1),
190191 ansi.NewStyle().Underline(false).String(),
internal/ui/model/header.go+2−1
@@ -122,7 +122,8 @@ func (h *header) drawHeader(
122122 b.WriteString(details)
123123
124124 view := uv.NewStyledString(
125− t.Header.Wrapper.Padding(0, rightPadding, 0, leftPadding).Render(b.String()))
125+ t.Header.Wrapper.Padding(0, rightPadding, 0, leftPadding).Render(b.String()),
126+ )
126127 view.Draw(scr, area)
127128}
128129
internal/ui/model/ui.go+22−11
@@ -2301,7 +2301,8 @@ func (m *UI) ShortHelp() []key.Binding {
23012301 tab.SetHelp("tab", "focus editor")
23022302 }
23032303
2304− binds = append(binds,
2304+ binds = append(
2305+ binds,
23052306 tab,
23062307 commands,
23072308 k.Models,
@@ -2309,11 +2310,13 @@ func (m *UI) ShortHelp() []key.Binding {
23092310
23102311 switch m.focus {
23112312 case uiFocusEditor:
2312− binds = append(binds,
2313+ binds = append(
2314+ binds,
23132315 k.Editor.Newline,
23142316 )
23152317 case uiFocusMain:
2316− binds = append(binds,
2318+ binds = append(
2319+ binds,
23172320 k.Chat.UpDown,
23182321 k.Chat.UpDownOneItem,
23192322 k.Chat.PageUp,
@@ -2328,14 +2331,16 @@ func (m *UI) ShortHelp() []key.Binding {
23282331 // TODO: other states
23292332 // if m.session == nil {
23302333 // no session selected
2331− binds = append(binds,
2334+ binds = append(
2335+ binds,
23322336 commands,
23332337 k.Models,
23342338 k.Editor.Newline,
23352339 )
23362340 }
23372341
2338− binds = append(binds,
2342+ binds = append(
2343+ binds,
23392344 k.Quit,
23402345 k.Help,
23412346 )
@@ -2382,7 +2387,8 @@ func (m *UI) FullHelp() [][]key.Binding {
23822387 tab.SetHelp("tab", "focus editor")
23832388 }
23842389
2385− mainBinds = append(mainBinds,
2390+ mainBinds = append(
2391+ mainBinds,
23862392 tab,
23872393 commands,
23882394 k.Models,
@@ -2406,7 +2412,8 @@ func (m *UI) FullHelp() [][]key.Binding {
24062412 }
24072413 binds = append(binds, editorBinds)
24082414 if hasAttachments {
2409− binds = append(binds,
2415+ binds = append(
2416+ binds,
24102417 []key.Binding{
24112418 k.Editor.AttachmentDeleteMode,
24122419 k.Editor.DeleteAllAttachments,
@@ -2415,7 +2422,8 @@ func (m *UI) FullHelp() [][]key.Binding {
24152422 )
24162423 }
24172424 case uiFocusMain:
2418− binds = append(binds,
2425+ binds = append(
2426+ binds,
24192427 []key.Binding{
24202428 k.Chat.UpDown,
24212429 k.Chat.UpDownOneItem,
@@ -2440,7 +2448,8 @@ func (m *UI) FullHelp() [][]key.Binding {
24402448 default:
24412449 if m.session == nil {
24422450 // no session selected
2443− binds = append(binds,
2451+ binds = append(
2452+ binds,
24442453 []key.Binding{
24452454 commands,
24462455 k.Models,
@@ -2457,7 +2466,8 @@ func (m *UI) FullHelp() [][]key.Binding {
24572466 }
24582467 binds = append(binds, editorBinds)
24592468 if hasAttachments {
2460− binds = append(binds,
2469+ binds = append(
2470+ binds,
24612471 []key.Binding{
24622472 k.Editor.AttachmentDeleteMode,
24632473 k.Editor.DeleteAllAttachments,
@@ -2468,7 +2478,8 @@ func (m *UI) FullHelp() [][]key.Binding {
24682478 }
24692479 }
24702480
2471− binds = append(binds,
2481+ binds = append(
2482+ binds,
24722483 []key.Binding{
24732484 help,
24742485 k.Quit,