diff --git a/internal/agent/agent.go b/internal/agent/agent.go index ba1215e9a22ca425f745e6e00c85908737d50a0e..e8707a3e2b3e35281e57a9d396adbe81c5b7ebbd 100644 --- a/internal/agent/agent.go +++ b/internal/agent/agent.go @@ -668,7 +668,8 @@ func (a *sessionAgent) Summarize(ctx context.Context, sessionID string, opts fan } }() - agent := fantasy.NewAgent(largeModel.Model, + agent := fantasy.NewAgent( + largeModel.Model, fantasy.WithSystemPrompt(string(summaryPrompt)), fantasy.WithUserAgent(userAgent), ) @@ -814,7 +815,8 @@ func (a *sessionAgent) preparePrompt(msgs []message.Message, supportsImages bool var history []fantasy.Message if !a.isSubAgent { history = append(history, fantasy.NewUserMessage( - fmt.Sprintf("%s", + fmt.Sprintf( + "%s", `This is a reminder that your todo list is currently empty. DO NOT mention this to the user explicitly because they are already aware. If you are working on tasks that would benefit from a todo list please use the "todos" tool to create one. If 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 if _, known := knownToolCallIDs[tr.ToolCallID]; known { validParts = append(validParts, part) } else { - slog.Warn("Dropping orphaned tool result with no matching tool call", + slog.Warn( + "Dropping orphaned tool result with no matching tool call", "tool_call_id", tr.ToolCallID, ) } @@ -946,7 +949,8 @@ func syntheticToolResultsForOrphanedCalls(m message.Message, knownToolResultIDs if _, hasResult := knownToolResultIDs[tc.ID]; hasResult { continue } - slog.Warn("Injecting synthetic tool result for orphaned tool call", + slog.Warn( + "Injecting synthetic tool result for orphaned tool call", "tool_call_id", tc.ID, "tool_name", tc.Name, ) @@ -1004,7 +1008,8 @@ func (a *sessionAgent) generateTitle(ctx context.Context, sessionID string, user } newAgent := func(m fantasy.LanguageModel, p []byte, tok int64) fantasy.Agent { - return fantasy.NewAgent(m, + return fantasy.NewAgent( + m, fantasy.WithSystemPrompt(string(p)+"\n /no_think"), fantasy.WithMaxOutputTokens(tok), fantasy.WithUserAgent(userAgent), @@ -1273,7 +1278,8 @@ func (a *sessionAgent) convertToToolResult(result fantasy.ToolResultContent) mes case fantasy.ToolResultContentTypeMedia: if r, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentMedia](result.Result); ok { if !stringext.IsValidBase64(r.Data) { - slog.Warn("Tool returned media with invalid base64 data, discarding image", + slog.Warn( + "Tool returned media with invalid base64 data, discarding image", "tool", result.ToolName, "tool_call_id", result.ToolCallID, ) diff --git a/internal/agent/agent_tool.go b/internal/agent/agent_tool.go index b009d319a9475df5548438974c803c5130750c44..5be58c842ed30c5a2b9f713d5840997e94688dc3 100644 --- a/internal/agent/agent_tool.go +++ b/internal/agent/agent_tool.go @@ -63,5 +63,6 @@ func (c *coordinator) agentTool(ctx context.Context) (fantasy.AgentTool, error) Prompt: params.Prompt, SessionTitle: "New Agent Session", }) - }), nil + }, + ), nil } diff --git a/internal/agent/agentic_fetch_tool.go b/internal/agent/agentic_fetch_tool.go index edd9370a4b5bd5934dec9537821cf079babbcfbb..ef8f44e981eceadcf113a1fe251028de06e4c6a3 100644 --- a/internal/agent/agentic_fetch_tool.go +++ b/internal/agent/agentic_fetch_tool.go @@ -80,7 +80,8 @@ func (c *coordinator) agenticFetchTool(_ context.Context, client *http.Client) ( description = "Search the web and analyze results" } - p, err := c.permissions.Request(ctx, + p, err := c.permissions.Request( + ctx, permission.CreatePermissionRequest{ SessionID: validationResult.SessionID, Path: c.cfg.WorkingDir(), @@ -200,5 +201,6 @@ func (c *coordinator) agenticFetchTool(_ context.Context, client *http.Client) ( c.permissions.AutoApproveSession(sessionID) }, }) - }), nil + }, + ), nil } diff --git a/internal/agent/coordinator.go b/internal/agent/coordinator.go index e3a610f2cc27a9f3c42db6635e436f2f7ddb0866..f3703fc3099cf3b94baa9682fa48c1b1295d12a3 100644 --- a/internal/agent/coordinator.go +++ b/internal/agent/coordinator.go @@ -491,7 +491,8 @@ func (c *coordinator) buildTools(ctx context.Context, agent config.Agent, isSubA hookRunner = hooks.NewRunner(preToolHooks, c.cfg.WorkingDir(), c.cfg.WorkingDir()) } - allTools = append(allTools, + allTools = append( + allTools, tools.NewBashTool(c.permissions, c.cfg.WorkingDir(), c.cfg.Config().Options.Attribution, modelID), tools.NewCrushInfoTool(c.cfg, c.lspManager, c.allSkills, c.activeSkills, c.skillTracker), tools.NewCrushLogsTool(logFile), @@ -740,7 +741,8 @@ func (c *coordinator) buildOpenaiCompatProvider(baseURL, apiKey string, headers // Set HTTP client based on provider and debug mode. var httpClient *http.Client if providerID == string(catwalk.InferenceProviderCopilot) { - opts = append(opts, + opts = append( + opts, openaicompat.WithUseResponsesAPI(), openaicompat.WithResponsesAPIFunc(func(modelID string) bool { return copilotResponsesModels[modelID] @@ -1213,7 +1215,8 @@ func logTurnSkillUsage( } } - slog.Info("Skill turn summary", + slog.Info( + "Skill turn summary", "component", "skills", "session_id", sessionID, "prompt_len", len(prompt), @@ -1257,7 +1260,8 @@ func logDiscoveryStats( xml := skills.ToPromptXML(activeSkills) - slog.Info("Skill discovery complete", + slog.Info( + "Skill discovery complete", "component", "skills", "builtin_ok", len(builtin), "builtin_errors", countErrors(builtinStates), diff --git a/internal/agent/tools/bash.go b/internal/agent/tools/bash.go index d623d58bc418cf2810958f86ecb2472724129deb..ba6b224ef82ea28be7ea299be49703dcba82174f 100644 --- a/internal/agent/tools/bash.go +++ b/internal/agent/tools/bash.go @@ -219,7 +219,8 @@ func NewBashTool(permissions permission.Service, workingDir string, attribution return fantasy.ToolResponse{}, fmt.Errorf("session ID is required for executing shell command") } if !isSafeReadOnly { - p, err := permissions.Request(ctx, + p, err := permissions.Request( + ctx, permission.CreatePermissionRequest{ SessionID: sessionID, Path: execWorkingDir, @@ -375,7 +376,8 @@ func NewBashTool(permissions permission.Service, workingDir string, attribution } 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) return fantasy.WithResponseMetadata(fantasy.NewTextResponse(response), metadata), nil - }) + }, + ) } // formatOutput formats the output of a completed command with error handling diff --git a/internal/agent/tools/crush_info.go b/internal/agent/tools/crush_info.go index 045d88c339a32a5821f8834e210d5e6637cc9e5b..9d4fff4ad6006bc7b7276c8b7627b9eeb6cfea80 100644 --- a/internal/agent/tools/crush_info.go +++ b/internal/agent/tools/crush_info.go @@ -33,7 +33,8 @@ func NewCrushInfoTool( crushInfoDescription, func(ctx context.Context, _ CrushInfoParams, _ fantasy.ToolCall) (fantasy.ToolResponse, error) { return fantasy.NewTextResponse(buildCrushInfo(cfg, lspManager, allSkills, activeSkills, skillTracker)), nil - }) + }, + ) } func buildCrushInfo(cfg *config.ConfigStore, lspManager *lsp.Manager, allSkills []*skills.Skill, activeSkills []*skills.Skill, skillTracker *skills.Tracker) string { diff --git a/internal/agent/tools/diagnostics.go b/internal/agent/tools/diagnostics.go index 561ba176bd47700c2fec67418e4e1d6cc145a2df..ecda0bbab4462d47ea4f0d357437fd247734b6b1 100644 --- a/internal/agent/tools/diagnostics.go +++ b/internal/agent/tools/diagnostics.go @@ -35,7 +35,8 @@ func NewDiagnosticsTool(lspManager *lsp.Manager) fantasy.AgentTool { notifyLSPs(ctx, lspManager, params.FilePath) output := getDiagnostics(params.FilePath, lspManager) return fantasy.NewTextResponse(output), nil - }) + }, + ) } // openInLSPs ensures LSP servers are running and aware of the file, but does diff --git a/internal/agent/tools/download.go b/internal/agent/tools/download.go index 1e04f9980cb35f595088dfc81d6572dd65351a58..9aaa94620fd98c3ac34bc9ea85d37481b70022b2 100644 --- a/internal/agent/tools/download.go +++ b/internal/agent/tools/download.go @@ -87,7 +87,8 @@ func NewDownloadTool(permissions permission.Service, workingDir string, client * return fantasy.ToolResponse{}, fmt.Errorf("session ID is required for downloading files") } - p, err := permissions.Request(ctx, + p, err := permissions.Request( + ctx, permission.CreatePermissionRequest{ SessionID: sessionID, Path: filePath, @@ -160,5 +161,6 @@ func NewDownloadTool(permissions permission.Service, workingDir string, client * } return fantasy.NewTextResponse(responseMsg), nil - }) + }, + ) } diff --git a/internal/agent/tools/edit.go b/internal/agent/tools/edit.go index afafe1bc7f7be77e92e9e257458dcaee8a87e5be..c445a3f11cf0078f2ad5a823eacfe4fd88072d5d 100644 --- a/internal/agent/tools/edit.go +++ b/internal/agent/tools/edit.go @@ -104,7 +104,8 @@ func NewEditTool( text += getDiagnostics(params.FilePath, lspManager) response.Content = text return response, nil - }) + }, + ) } func 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 content, strings.TrimPrefix(filePath, edit.workingDir), ) - p, err := edit.permissions.Request(edit.ctx, + p, err := edit.permissions.Request( + edit.ctx, permission.CreatePermissionRequest{ SessionID: sessionID, Path: fsext.PathOrPrefix(filePath, edit.workingDir), @@ -213,9 +215,11 @@ func deleteContent(edit editContext, filePath, oldString string, replaceAll bool modTime := fileInfo.ModTime().Truncate(time.Second) if modTime.After(lastRead) { return fantasy.NewTextErrorResponse( - fmt.Sprintf("file %s has been modified since it was last read (mod time: %s, last read: %s)", + fmt.Sprintf( + "file %s has been modified since it was last read (mod time: %s, last read: %s)", filePath, modTime.Format(time.RFC3339), lastRead.Format(time.RFC3339), - )), nil + ), + ), nil } content, err := os.ReadFile(filePath) @@ -252,7 +256,8 @@ func deleteContent(edit editContext, filePath, oldString string, replaceAll bool strings.TrimPrefix(filePath, edit.workingDir), ) - p, err := edit.permissions.Request(edit.ctx, + p, err := edit.permissions.Request( + edit.ctx, permission.CreatePermissionRequest{ SessionID: sessionID, Path: fsext.PathOrPrefix(filePath, edit.workingDir), @@ -344,9 +349,11 @@ func replaceContent(edit editContext, filePath, oldString, newString string, rep modTime := fileInfo.ModTime().Truncate(time.Second) if modTime.After(lastRead) { return fantasy.NewTextErrorResponse( - fmt.Sprintf("file %s has been modified since it was last read (mod time: %s, last read: %s)", + fmt.Sprintf( + "file %s has been modified since it was last read (mod time: %s, last read: %s)", filePath, modTime.Format(time.RFC3339), lastRead.Format(time.RFC3339), - )), nil + ), + ), nil } content, err := os.ReadFile(filePath) @@ -383,7 +390,8 @@ func replaceContent(edit editContext, filePath, oldString, newString string, rep strings.TrimPrefix(filePath, edit.workingDir), ) - p, err := edit.permissions.Request(edit.ctx, + p, err := edit.permissions.Request( + edit.ctx, permission.CreatePermissionRequest{ SessionID: sessionID, Path: fsext.PathOrPrefix(filePath, edit.workingDir), @@ -445,5 +453,6 @@ func replaceContent(edit editContext, filePath, oldString, newString string, rep NewContent: newContent, Additions: additions, Removals: removals, - }), nil + }, + ), nil } diff --git a/internal/agent/tools/fetch.go b/internal/agent/tools/fetch.go index 599a32f84c0c33eeaeee65385be2613e635544fc..41def3959863914728a0fc6955f092da8a2a1ee3 100644 --- a/internal/agent/tools/fetch.go +++ b/internal/agent/tools/fetch.go @@ -77,7 +77,8 @@ func NewFetchTool(permissions permission.Service, workingDir string, client *htt return fantasy.ToolResponse{}, fmt.Errorf("session ID is required for creating a new file") } - p, err := permissions.Request(ctx, + p, err := permissions.Request( + ctx, permission.CreatePermissionRequest{ SessionID: sessionID, Path: workingDir, @@ -184,7 +185,8 @@ func NewFetchTool(permissions permission.Service, workingDir string, client *htt } return fantasy.NewTextResponse(content), nil - }) + }, + ) } func extractTextFromHTML(html string) (string, error) { diff --git a/internal/agent/tools/glob.go b/internal/agent/tools/glob.go index d9c3162e755a655eca78f448c3d523c6e862523d..1f2c88803a78c70cd142957c6b2df30eb7bfbe64 100644 --- a/internal/agent/tools/glob.go +++ b/internal/agent/tools/glob.go @@ -82,7 +82,8 @@ func NewGlobTool(workingDir string) fantasy.AgentTool { Truncated: truncated, }, ), nil - }) + }, + ) } func globFiles(ctx context.Context, pattern, searchPath string, limit int) ([]string, bool, error) { diff --git a/internal/agent/tools/grep.go b/internal/agent/tools/grep.go index 52e70f9ab9eaeba202375d69dd8723a8bef71524..f8a8f7a6a8e9c732cd95a50b16b5b36b3c07a19b 100644 --- a/internal/agent/tools/grep.go +++ b/internal/agent/tools/grep.go @@ -186,7 +186,8 @@ func NewGrepTool(workingDir string, config config.ToolGrep) fantasy.AgentTool { Truncated: truncated, }, ), nil - }) + }, + ) } func searchFiles(ctx context.Context, pattern, rootPath, include string, limit int) ([]grepMatch, bool, error) { diff --git a/internal/agent/tools/job_kill.go b/internal/agent/tools/job_kill.go index bd0e7e8fcda42b08f9eb9fd7ed1eabbc8e7029dd..cb462afadf99d6b1dda30b31fd1badc6fb75054a 100644 --- a/internal/agent/tools/job_kill.go +++ b/internal/agent/tools/job_kill.go @@ -55,5 +55,6 @@ func NewJobKillTool() fantasy.AgentTool { result := fmt.Sprintf("Background shell %s terminated successfully", params.ShellID) return fantasy.WithResponseMetadata(fantasy.NewTextResponse(result), metadata), nil - }) + }, + ) } diff --git a/internal/agent/tools/job_output.go b/internal/agent/tools/job_output.go index 783487c2e23695ee8685f8f7f12e6fc0208ae86c..07284bbdcaf9dfce72b063d465087d6f3dcfa62c 100644 --- a/internal/agent/tools/job_output.go +++ b/internal/agent/tools/job_output.go @@ -87,5 +87,6 @@ func NewJobOutputTool() fantasy.AgentTool { result := fmt.Sprintf("Status: %s\n\n%s", status, output) return fantasy.WithResponseMetadata(fantasy.NewTextResponse(result), metadata), nil - }) + }, + ) } diff --git a/internal/agent/tools/list_mcp_resources.go b/internal/agent/tools/list_mcp_resources.go index 983970a08231fe749816e3b5bc50eac09875844d..fb570e3e2caeec8ab0e41a18449710a230fd9ccc 100644 --- a/internal/agent/tools/list_mcp_resources.go +++ b/internal/agent/tools/list_mcp_resources.go @@ -44,7 +44,8 @@ func NewListMCPResourcesTool(cfg *config.ConfigStore, permissions permission.Ser } relPath := filepathext.SmartJoin(cfg.WorkingDir(), params.MCPName) - p, err := permissions.Request(ctx, + p, err := permissions.Request( + ctx, permission.CreatePermissionRequest{ SessionID: sessionID, Path: relPath, diff --git a/internal/agent/tools/ls.go b/internal/agent/tools/ls.go index 750e5797836b5efd884d9fe47b039ab4e00cc95a..8b108192c4427a58f7063c6f56528067a512675f 100644 --- a/internal/agent/tools/ls.go +++ b/internal/agent/tools/ls.go @@ -102,7 +102,8 @@ func NewLsTool(permissions permission.Service, workingDir string, lsConfig confi return fantasy.ToolResponse{}, fmt.Errorf("session ID is required for accessing directories outside working directory") } - granted, err := permissions.Request(ctx, + granted, err := permissions.Request( + ctx, permission.CreatePermissionRequest{ SessionID: sessionID, Path: absSearchPath, @@ -130,7 +131,8 @@ func NewLsTool(permissions permission.Service, workingDir string, lsConfig confi fantasy.NewTextResponse(output), metadata, ), nil - }) + }, + ) } func ListDirectoryTree(searchPath string, params LSParams, lsConfig config.ToolLs) (string, LSResponseMetadata, error) { diff --git a/internal/agent/tools/lsp_restart.go b/internal/agent/tools/lsp_restart.go index 544bc325aed3864fa2f4072e0f29414e99296a0c..1369ae7c978502ad5580fce18a0b65b4075db080 100644 --- a/internal/agent/tools/lsp_restart.go +++ b/internal/agent/tools/lsp_restart.go @@ -75,5 +75,6 @@ func NewLSPRestartTool(lspManager *lsp.Manager) fantasy.AgentTool { } return fantasy.NewTextResponse(output), nil - }) + }, + ) } diff --git a/internal/agent/tools/mcp-tools.go b/internal/agent/tools/mcp-tools.go index 5e92247b8d21f0cbe0e2055a6f97d6965cdaf91c..8921daea56912d8a5ec0a1c4ff7380918c65424e 100644 --- a/internal/agent/tools/mcp-tools.go +++ b/internal/agent/tools/mcp-tools.go @@ -105,7 +105,8 @@ func (m *Tool) Run(ctx context.Context, params fantasy.ToolCall) (fantasy.ToolRe // Skip permission for whitelisted Docker MCP tools. if !slices.Contains(whitelistDockerTools, params.Name) { permissionDescription := fmt.Sprintf("execute %s with the following parameters:", m.Info().Name) - p, err := m.permissions.Request(ctx, + p, err := m.permissions.Request( + ctx, permission.CreatePermissionRequest{ SessionID: sessionID, ToolCallID: params.ID, diff --git a/internal/agent/tools/multiedit.go b/internal/agent/tools/multiedit.go index 34d060f42bc1cc9be0dac78c740e58a1da804b61..270acc3d3cfee2b33cf0e3b7264f71958738004c 100644 --- a/internal/agent/tools/multiedit.go +++ b/internal/agent/tools/multiedit.go @@ -110,7 +110,8 @@ func NewMultiEditTool( text += getDiagnostics(params.FilePath, lspManager) response.Content = text return response, nil - }) + }, + ) } func validateEdits(edits []MultiEditOperation) error { @@ -266,9 +267,11 @@ func processMultiEditExistingFile(edit editContext, params MultiEditParams, call modTime := fileInfo.ModTime().Truncate(time.Second) if modTime.After(lastRead) { return fantasy.NewTextErrorResponse( - fmt.Sprintf("file %s has been modified since it was last read (mod time: %s, last read: %s)", + fmt.Sprintf( + "file %s has been modified since it was last read (mod time: %s, last read: %s)", params.FilePath, modTime.Format(time.RFC3339), lastRead.Format(time.RFC3339), - )), nil + ), + ), nil } // Read current file content diff --git a/internal/agent/tools/read_mcp_resource.go b/internal/agent/tools/read_mcp_resource.go index 6b613cfbf97e07f32435d1c776dd54dbb646c725..eadd6233dff0af123efc7afa4009a3651174e1e5 100644 --- a/internal/agent/tools/read_mcp_resource.go +++ b/internal/agent/tools/read_mcp_resource.go @@ -50,7 +50,8 @@ func NewReadMCPResourceTool(cfg *config.ConfigStore, permissions permission.Serv } relPath := filepathext.SmartJoin(cfg.WorkingDir(), cmp.Or(params.URI, "mcp-resource")) - p, err := permissions.Request(ctx, + p, err := permissions.Request( + ctx, permission.CreatePermissionRequest{ SessionID: sessionID, Path: relPath, diff --git a/internal/agent/tools/references.go b/internal/agent/tools/references.go index 9600f30b066259d8e6822cd063ae2b0bb342687d..3839cdefa17028992581843bc58fdcdd8ed4d836 100644 --- a/internal/agent/tools/references.go +++ b/internal/agent/tools/references.go @@ -87,7 +87,8 @@ func NewReferencesTool(lspManager *lsp.Manager) fantasy.AgentTool { return fantasy.NewTextErrorResponse(allErrs.Error()), nil } return fantasy.NewTextResponse(fmt.Sprintf("No references found for symbol '%s'", params.Symbol)), nil - }) + }, + ) } func (r *referencesTool) Name() string { diff --git a/internal/agent/tools/sourcegraph.go b/internal/agent/tools/sourcegraph.go index ee7de67a6674ade83f19f2a78badda3e1c16bde2..e0b01d035e6d3e5ede2c4c12955b422292784f28 100644 --- a/internal/agent/tools/sourcegraph.go +++ b/internal/agent/tools/sourcegraph.go @@ -150,7 +150,8 @@ func NewSourcegraphTool(client *http.Client) fantasy.AgentTool { } return fantasy.NewTextResponse(formattedResults), nil - }) + }, + ) } func formatSourcegraphResults(result map[string]any, contextWindow int) (string, error) { diff --git a/internal/agent/tools/todos.go b/internal/agent/tools/todos.go index e99d2a7514b0d211b79aab6fcb4764965848fc24..e57c4d19b9276d52ac374d4276a649e9f9732da0 100644 --- a/internal/agent/tools/todos.go +++ b/internal/agent/tools/todos.go @@ -130,5 +130,6 @@ func NewTodosTool(sessions session.Service) fantasy.AgentTool { } return fantasy.WithResponseMetadata(fantasy.NewTextResponse(response), metadata), nil - }) + }, + ) } diff --git a/internal/agent/tools/view.go b/internal/agent/tools/view.go index 16edff9287cb6370dfd3b80826d269d6476a1727..e62329ff95d45e63e18424a935e79150ab29d369 100644 --- a/internal/agent/tools/view.go +++ b/internal/agent/tools/view.go @@ -134,7 +134,8 @@ func NewViewTool( // Request permission for files outside working directory, unless it's a skill file. if isOutsideWorkDir && !isSkillFile { - granted, permReqErr := permissions.Request(ctx, + granted, permReqErr := permissions.Request( + ctx, permission.CreatePermissionRequest{ SessionID: sessionID, Path: absFilePath, @@ -274,7 +275,8 @@ func NewViewTool( fantasy.NewTextResponse(output), meta, ), nil - }) + }, + ) } func addLineNumbers(content string, startLine int) string { diff --git a/internal/agent/tools/web_fetch.go b/internal/agent/tools/web_fetch.go index f52c29c60f440e631b97ed3700ccc084cefbf7a5..3bb6e98b79f7c422345ced9152def732464e1e05 100644 --- a/internal/agent/tools/web_fetch.go +++ b/internal/agent/tools/web_fetch.go @@ -75,5 +75,6 @@ func NewWebFetchTool(workingDir string, client *http.Client) fantasy.AgentTool { } return fantasy.NewTextResponse(result.String()), nil - }) + }, + ) } diff --git a/internal/agent/tools/web_search.go b/internal/agent/tools/web_search.go index 22af0c38938cc8d38e013bb1d014b60e5d57cb41..6215a772858d8551fbf1ab24596e6f4ae9d0a484 100644 --- a/internal/agent/tools/web_search.go +++ b/internal/agent/tools/web_search.go @@ -57,5 +57,6 @@ func NewWebSearchTool(client *http.Client) fantasy.AgentTool { } return fantasy.NewTextResponse(formatSearchResults(results)), nil - }) + }, + ) } diff --git a/internal/agent/tools/write.go b/internal/agent/tools/write.go index 41b3d5961639330d15584378317670fdcd8a2997..c76e244b1926698bd5c61001f5eaf3209949ab84 100644 --- a/internal/agent/tools/write.go +++ b/internal/agent/tools/write.go @@ -105,7 +105,8 @@ func NewWriteTool( strings.TrimPrefix(filePath, workingDir), ) - p, err := permissions.Request(ctx, + p, err := permissions.Request( + ctx, permission.CreatePermissionRequest{ SessionID: sessionID, Path: fsext.PathOrPrefix(filePath, workingDir), @@ -161,12 +162,14 @@ func NewWriteTool( result := fmt.Sprintf("File successfully written: %s", filePath) result = fmt.Sprintf("\n%s\n", result) result += getDiagnostics(filePath, lspManager) - return fantasy.WithResponseMetadata(fantasy.NewTextResponse(result), + return fantasy.WithResponseMetadata( + fantasy.NewTextResponse(result), WriteResponseMetadata{ Diff: diff, Additions: additions, Removals: removals, }, ), nil - }) + }, + ) } diff --git a/internal/backend/backend.go b/internal/backend/backend.go index 370bdbdcf706f2b25f17bfb53e54c041e473b586..642b48a9222de132ffd24f9c356d4b7152a38591 100644 --- a/internal/backend/backend.go +++ b/internal/backend/backend.go @@ -122,7 +122,8 @@ func (b *Backend) CreateWorkspace(args proto.Workspace) (*Workspace, proto.Works b.workspaces.Set(id, ws) if args.Version != "" && args.Version != version.Version { - slog.Warn("Client/server version mismatch", + slog.Warn( + "Client/server version mismatch", "client", args.Version, "server", version.Version, ) diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 0c02064507caa544100f57953ab8a6dde6f1ff4f..3f5971c01262b3375ee8c6becef91de96afc4483 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -486,7 +486,8 @@ func perHostServerDir(hostURL *url.URL) (string, error) { // the --host flag so client and server compute the same key. func safeHostName(hostURL *url.URL) string { return safeNameRegexp.ReplaceAllString( - hostURL.Scheme+"://"+hostURL.Host+hostURL.Path, "_") + hostURL.Scheme+"://"+hostURL.Host+hostURL.Path, "_", + ) } // serverReadyTimeout returns the total budget for the readiness probe. diff --git a/internal/config/load_test.go b/internal/config/load_test.go index 8f7dd60b3189c25caea05448e046142e908cefb0..026c8971555f49d910f658ff9a0c61f4c0438b11 100644 --- a/internal/config/load_test.go +++ b/internal/config/load_test.go @@ -248,7 +248,8 @@ func TestConfig_setDefaults(t *testing.T) { cfg := &Config{} cfg.setDefaults(child, "") - require.Equal(t, + require.Equal( + t, filepath.Clean(filepath.Join(child, defaultDataDirectory)), filepath.Clean(cfg.Options.DataDirectory), ) diff --git a/internal/event/event_test.go b/internal/event/event_test.go index 17a44568453f251f6b77ab8749c10a8cd92d7f15..447e9939c757c1788779bed1b349feea97bc45fe 100644 --- a/internal/event/event_test.go +++ b/internal/event/event_test.go @@ -54,7 +54,8 @@ func TestError(t *testing.T) { }() client = nil - Error("test error", + Error( + "test error", "type", "test", "severity", "high", "source", "unit-test", diff --git a/internal/hooks/hooks.go b/internal/hooks/hooks.go index 4d1c8bfc72c3857f87d4732421867fda8ef9ea8c..3529dc2a95b378b85b29f21a7e71ae34432d1306 100644 --- a/internal/hooks/hooks.go +++ b/internal/hooks/hooks.go @@ -128,7 +128,8 @@ func aggregate(results []HookResult, origToolInput string) AggregateResult { if r.UpdatedInput != "" { next, err := shallowMerge(merged, r.UpdatedInput) if err != nil { - slog.Warn("Hook updated_input patch rejected; ignoring", + slog.Warn( + "Hook updated_input patch rejected; ignoring", "error", err, "patch", r.UpdatedInput, ) diff --git a/internal/hooks/hooks_test.go b/internal/hooks/hooks_test.go index 77217e77354367a07d8a2a8e172152b2281e3643..482833e00d16ce1fd88cca1d91a3a5913cda0733 100644 --- a/internal/hooks/hooks_test.go +++ b/internal/hooks/hooks_test.go @@ -538,7 +538,8 @@ func TestAggregationUpdatedInput(t *testing.T) { require.Equal(t, DecisionAllow, agg.Decision) // command overridden by second patch; keep preserved from first // patch; timeout preserved from original input. - require.JSONEq(t, + require.JSONEq( + t, `{"command":"second","keep":"me","timeout":60}`, agg.UpdatedInput, ) @@ -550,7 +551,8 @@ func TestAggregationUpdatedInput(t *testing.T) { {Decision: DecisionAllow, UpdatedInput: `{"env":{"FOO":"bar"}}`}, }, `{"env":{"BAZ":"qux"},"command":"ls"}`) // "env" is replaced entirely; "command" preserved. - require.JSONEq(t, + require.JSONEq( + t, `{"env":{"FOO":"bar"},"command":"ls"}`, agg.UpdatedInput, ) @@ -678,7 +680,8 @@ func TestRunnerUpdatedInput(t *testing.T) { result, err := r.Run(context.Background(), EventPreToolUse, "sess", "bash", `{"command":"echo original","timeout":60}`) require.NoError(t, err) require.Equal(t, DecisionAllow, result.Decision) - require.JSONEq(t, + require.JSONEq( + t, `{"command":"echo rewritten","timeout":60}`, result.UpdatedInput, ) diff --git a/internal/hooks/input.go b/internal/hooks/input.go index dfe1a52a42abb26eb81b8db1ffcbbf13c17544f8..08d45dbb92287bbd8b929d2b9af0e4922ac64a60 100644 --- a/internal/hooks/input.go +++ b/internal/hooks/input.go @@ -53,7 +53,8 @@ func BuildPayload(eventName, sessionID, cwd, toolName, toolInputJSON string) []b func BuildEnv(eventName, toolName, sessionID, cwd, projectDir, toolInputJSON string) []string { env := os.Environ() env = append(env, shell.CrushEnvMarkers()...) - env = append(env, + env = append( + env, fmt.Sprintf("CRUSH_EVENT=%s", eventName), fmt.Sprintf("CRUSH_TOOL_NAME=%s", toolName), fmt.Sprintf("CRUSH_SESSION_ID=%s", sessionID), @@ -105,7 +106,8 @@ func parseStdout(stdout string) HookResult { } if parsed.Version > SupportedOutputVersion { - slog.Debug("Hook output declared a newer envelope version than this build supports", + slog.Debug( + "Hook output declared a newer envelope version than this build supports", "version", parsed.Version, "supported", SupportedOutputVersion, ) diff --git a/internal/hooks/runner.go b/internal/hooks/runner.go index be625b0f10f3d97b4c67220dce3d96720797eb52..abc2393fa0b5c156044633c991568a669c4689e9 100644 --- a/internal/hooks/runner.go +++ b/internal/hooks/runner.go @@ -54,7 +54,8 @@ func NewRunner(hooks []config.HookConfig, cwd, projectDir string) *Runner { if h.Matcher != "" { re, err := regexp.Compile(h.Matcher) if err != nil { - slog.Warn("Hook matcher failed to compile; skipping hook", + slog.Warn( + "Hook matcher failed to compile; skipping hook", "matcher", h.Matcher, "command", h.Command, "error", err, @@ -130,7 +131,8 @@ func (r *Runner) Run(ctx context.Context, eventName, sessionID, toolName, toolIn InputRewrite: results[i].UpdatedInput != "", } } - slog.Info("Hook completed", + slog.Info( + "Hook completed", "event", eventName, "tool", toolName, "hooks", len(deduped), @@ -194,7 +196,8 @@ func (r *Runner) runOne(parentCtx context.Context, hook config.HookConfig, envVa case err = <-done: // Interpreter yielded within the grace period; safe to read. case <-time.After(abandonGrace): - slog.Warn("Hook did not yield after cancel; abandoning goroutine", + slog.Warn( + "Hook did not yield after cancel; abandoning goroutine", "command", hook.Command, "timeout", timeout, ) @@ -240,7 +243,8 @@ func (r *Runner) runOne(parentCtx context.Context, hook config.HookConfig, envVa } default: // Other non-zero exits are non-blocking errors. - slog.Warn("Hook failed with non-blocking error", + slog.Warn( + "Hook failed with non-blocking error", "command", hook.Command, "exit_code", exitCode, "stderr", strings.TrimSpace(stderr.String()), @@ -252,7 +256,8 @@ func (r *Runner) runOne(parentCtx context.Context, hook config.HookConfig, envVa // Exit code 0 — parse stdout JSON. result := parseStdout(stdout.String()) - slog.Debug("Hook executed", + slog.Debug( + "Hook executed", "command", hook.Command, "decision", result.Decision.String(), ) diff --git a/internal/proto/agent.go b/internal/proto/agent.go index 2deb906afb24c8da0f774276229dc1bcc100a813..e5266e52614a5bc43065ff62cf18b16f8ee7401f 100644 --- a/internal/proto/agent.go +++ b/internal/proto/agent.go @@ -51,7 +51,7 @@ func (e AgentEvent) MarshalJSON() ([]byte, error) { } return "" }(), - Alias: (Alias)(e), + Alias: Alias(e), }) } @@ -62,7 +62,7 @@ func (e *AgentEvent) UnmarshalJSON(data []byte) error { Error string `json:"error,omitempty"` Alias }{ - Alias: (Alias)(*e), + Alias: Alias(*e), } if err := json.Unmarshal(data, &aux); err != nil { return err diff --git a/internal/proto/mcp.go b/internal/proto/mcp.go index cc9dcbe78bd89c7176fc67b9332798b844a4ddac..c8abeb668cd9ed0171222f5d2f892fe11cd5cd09 100644 --- a/internal/proto/mcp.go +++ b/internal/proto/mcp.go @@ -100,7 +100,7 @@ func (e MCPEvent) MarshalJSON() ([]byte, error) { } return "" }(), - Alias: (Alias)(e), + Alias: Alias(e), }) } @@ -111,7 +111,7 @@ func (e *MCPEvent) UnmarshalJSON(data []byte) error { Error string `json:"error,omitempty"` Alias }{ - Alias: (Alias)(*e), + Alias: Alias(*e), } if err := json.Unmarshal(data, &aux); err != nil { return err @@ -148,7 +148,7 @@ func (i MCPClientInfo) MarshalJSON() ([]byte, error) { } return "" }(), - Alias: (Alias)(i), + Alias: Alias(i), }) } @@ -159,7 +159,7 @@ func (i *MCPClientInfo) UnmarshalJSON(data []byte) error { Error string `json:"error,omitempty"` Alias }{ - Alias: (Alias)(*i), + Alias: Alias(*i), } if err := json.Unmarshal(data, &aux); err != nil { return err diff --git a/internal/proto/proto.go b/internal/proto/proto.go index 9c84c6c8bf0c2f14da75933f8eebd7a36ca534ba..5d4992ee0da71e1842ed696f1c3b8e05493cf06f 100644 --- a/internal/proto/proto.go +++ b/internal/proto/proto.go @@ -131,7 +131,7 @@ func (e LSPEvent) MarshalJSON() ([]byte, error) { } return "" }(), - Alias: (Alias)(e), + Alias: Alias(e), }) } @@ -142,7 +142,7 @@ func (e *LSPEvent) UnmarshalJSON(data []byte) error { Error string `json:"error,omitempty"` Alias }{ - Alias: (Alias)(*e), + Alias: Alias(*e), } if err := json.Unmarshal(data, &aux); err != nil { return err @@ -176,7 +176,7 @@ func (i LSPClientInfo) MarshalJSON() ([]byte, error) { } return "" }(), - Alias: (Alias)(i), + Alias: Alias(i), }) } @@ -187,7 +187,7 @@ func (i *LSPClientInfo) UnmarshalJSON(data []byte) error { Error string `json:"error,omitempty"` Alias }{ - Alias: (Alias)(*i), + Alias: Alias(*i), } if err := json.Unmarshal(data, &aux); err != nil { return err diff --git a/internal/server/logging.go b/internal/server/logging.go index 736e3d57cfb6697a07cc61a03c4157a42140df54..4a14fb60e86800d9c79ed9d4851f00f3fc21f730 100644 --- a/internal/server/logging.go +++ b/internal/server/logging.go @@ -15,7 +15,8 @@ func (s *Server) loggingHandler(next http.Handler) http.Handler { start := time.Now() lrw := &loggingResponseWriter{ResponseWriter: w, statusCode: http.StatusOK} - s.logger.Debug("HTTP request", + s.logger.Debug( + "HTTP request", slog.String("method", r.Method), slog.String("path", r.URL.Path), slog.String("remote_addr", r.RemoteAddr), @@ -25,7 +26,8 @@ func (s *Server) loggingHandler(next http.Handler) http.Handler { next.ServeHTTP(lrw, r) duration := time.Since(start) - s.logger.Debug("HTTP response", + s.logger.Debug( + "HTTP response", slog.String("method", r.Method), slog.String("path", r.URL.Path), slog.Int("status", lrw.statusCode), diff --git a/internal/shell/jq_test.go b/internal/shell/jq_test.go index e449047b49b27da9b2d587b6defe9d8f81fe2888..9b1ecb33023d989639803a26a7e0f0dcf49b7d66 100644 --- a/internal/shell/jq_test.go +++ b/internal/shell/jq_test.go @@ -185,7 +185,8 @@ func TestJQ_Success(t *testing.T) { t.Parallel() var stdout bytes.Buffer - err := handleJQ(t.Context(), + err := handleJQ( + t.Context(), []string{"jq", "-c", ".a"}, strings.NewReader(`{"a":1}`), &stdout, io.Discard, diff --git a/internal/ui/chat/tools.go b/internal/ui/chat/tools.go index 3774e217fa362dc80057a3e92707bdeeff9d07d3..9a4cf33af149af6d12b6e15b341bd98301734f94 100644 --- a/internal/ui/chat/tools.go +++ b/internal/ui/chat/tools.go @@ -690,9 +690,10 @@ func toolOutputCodeContent(sty *styles.Styles, path, content string, offset, wid // Add truncation message if needed. if len(lines) > maxLines && !expanded { - out = append(out, sty.Tool.ContentCodeTruncation. - Width(width). - Render(fmt.Sprintf(assistantMessageTruncateFormat, len(lines)-maxLines)), + out = append( + out, sty.Tool.ContentCodeTruncation. + Width(width). + Render(fmt.Sprintf(assistantMessageTruncateFormat, len(lines)-maxLines)), ) } @@ -851,7 +852,8 @@ func renderHookLine(sty *styles.Styles, hi hooks.HookInfo, rawName, detail strin arrowStyle = sty.Tool.HookDeniedLabel } - return fmt.Sprintf("%s %s%s%s %s %s", + return fmt.Sprintf( + "%s %s%s%s %s %s", labelStyle.Render("Hook"), name, namePad, @@ -1063,9 +1065,10 @@ func toolOutputMarkdownContent(sty *styles.Styles, content string, width int, ex } if len(lines) > maxLines && !expanded { - out = append(out, sty.Tool.ContentTruncation. - Width(width). - Render(fmt.Sprintf(assistantMessageTruncateFormat, len(lines)-maxLines)), + out = append( + out, sty.Tool.ContentTruncation. + Width(width). + Render(fmt.Sprintf(assistantMessageTruncateFormat, len(lines)-maxLines)), ) } diff --git a/internal/ui/dialog/commands.go b/internal/ui/dialog/commands.go index fd2fedf31ca267637e30700c69c2f1a973c7012c..a222124381e9058853c2170afb10016ce83a64ca 100644 --- a/internal/ui/dialog/commands.go +++ b/internal/ui/dialog/commands.go @@ -510,7 +510,8 @@ func (c *Commands) defaultCommands() []*CommandItem { } commands = append(commands, NewCommandItem(c.com.Styles, "toggle_notifications", notificationLabel, "", ActionToggleNotifications{})) - commands = append(commands, + commands = append( + commands, NewCommandItem(c.com.Styles, "toggle_yolo", "Toggle Yolo Mode", "", ActionToggleYoloMode{}), NewCommandItem(c.com.Styles, "toggle_help", "Toggle Help", "ctrl+g", ActionToggleHelp{}), NewCommandItem(c.com.Styles, "init", "Initialize Project", "", ActionInitializeProject{}), @@ -523,7 +524,8 @@ func (c *Commands) defaultCommands() []*CommandItem { } commands = append(commands, NewCommandItem(c.com.Styles, "toggle_transparent", transparentLabel, "", ActionToggleTransparentBackground{})) - commands = append(commands, + commands = append( + commands, NewCommandItem(c.com.Styles, "quit", "Quit", "ctrl+c", tea.QuitMsg{}).WithAliases("exit"), ) diff --git a/internal/ui/dialog/permissions.go b/internal/ui/dialog/permissions.go index c130f14b4b3c0a42929c1bbbf5447dc8e14aa303..4f158211514bfab5ac0ee4e857686b8105c359f3 100644 --- a/internal/ui/dialog/permissions.go +++ b/internal/ui/dialog/permissions.go @@ -775,7 +775,8 @@ func (p *Permissions) ShortHelp() []key.Binding { } if p.hasDiffView() { - bindings = append(bindings, + bindings = append( + bindings, p.keyMap.ToggleDiffMode, p.keyMap.ToggleFullscreen, ) diff --git a/internal/ui/dialog/sessions_item.go b/internal/ui/dialog/sessions_item.go index b7b8b00d3f3f914db7dc6cb13571ad6bd9899bed..32ba3a12d7d3b2f0a4a31a4da4e21c4349c41874 100644 --- a/internal/ui/dialog/sessions_item.go +++ b/internal/ui/dialog/sessions_item.go @@ -184,7 +184,8 @@ func renderItem(t ListItemStyles, title string, info string, focused bool, width // precisely via [ansi.AttrUnderline] and [ansi.AttrNoUnderline] // which only affect the underline attribute without interfering // with other style attributes. - parts = append(parts, + parts = append( + parts, ansi.NewStyle().Underline(true).String(), ansi.Cut(title, start, stop+1), ansi.NewStyle().Underline(false).String(), diff --git a/internal/ui/model/header.go b/internal/ui/model/header.go index 1fee1eb05942be52781173e8d63fab8de34a2f9b..c7091a6835c48f06a2eb0d4a504d1cc11b79f09c 100644 --- a/internal/ui/model/header.go +++ b/internal/ui/model/header.go @@ -122,7 +122,8 @@ func (h *header) drawHeader( b.WriteString(details) view := uv.NewStyledString( - t.Header.Wrapper.Padding(0, rightPadding, 0, leftPadding).Render(b.String())) + t.Header.Wrapper.Padding(0, rightPadding, 0, leftPadding).Render(b.String()), + ) view.Draw(scr, area) } diff --git a/internal/ui/model/ui.go b/internal/ui/model/ui.go index 6087c57cd584ae2302b59b3d28ac7e373b168108..6b60b503715307e23cb68282b8976a52136e27d7 100644 --- a/internal/ui/model/ui.go +++ b/internal/ui/model/ui.go @@ -2301,7 +2301,8 @@ func (m *UI) ShortHelp() []key.Binding { tab.SetHelp("tab", "focus editor") } - binds = append(binds, + binds = append( + binds, tab, commands, k.Models, @@ -2309,11 +2310,13 @@ func (m *UI) ShortHelp() []key.Binding { switch m.focus { case uiFocusEditor: - binds = append(binds, + binds = append( + binds, k.Editor.Newline, ) case uiFocusMain: - binds = append(binds, + binds = append( + binds, k.Chat.UpDown, k.Chat.UpDownOneItem, k.Chat.PageUp, @@ -2328,14 +2331,16 @@ func (m *UI) ShortHelp() []key.Binding { // TODO: other states // if m.session == nil { // no session selected - binds = append(binds, + binds = append( + binds, commands, k.Models, k.Editor.Newline, ) } - binds = append(binds, + binds = append( + binds, k.Quit, k.Help, ) @@ -2382,7 +2387,8 @@ func (m *UI) FullHelp() [][]key.Binding { tab.SetHelp("tab", "focus editor") } - mainBinds = append(mainBinds, + mainBinds = append( + mainBinds, tab, commands, k.Models, @@ -2406,7 +2412,8 @@ func (m *UI) FullHelp() [][]key.Binding { } binds = append(binds, editorBinds) if hasAttachments { - binds = append(binds, + binds = append( + binds, []key.Binding{ k.Editor.AttachmentDeleteMode, k.Editor.DeleteAllAttachments, @@ -2415,7 +2422,8 @@ func (m *UI) FullHelp() [][]key.Binding { ) } case uiFocusMain: - binds = append(binds, + binds = append( + binds, []key.Binding{ k.Chat.UpDown, k.Chat.UpDownOneItem, @@ -2440,7 +2448,8 @@ func (m *UI) FullHelp() [][]key.Binding { default: if m.session == nil { // no session selected - binds = append(binds, + binds = append( + binds, []key.Binding{ commands, k.Models, @@ -2457,7 +2466,8 @@ func (m *UI) FullHelp() [][]key.Binding { } binds = append(binds, editorBinds) if hasAttachments { - binds = append(binds, + binds = append( + binds, []key.Binding{ k.Editor.AttachmentDeleteMode, k.Editor.DeleteAllAttachments, @@ -2468,7 +2478,8 @@ func (m *UI) FullHelp() [][]key.Binding { } } - binds = append(binds, + binds = append( + binds, []key.Binding{ help, k.Quit,