mirror of
https://github.com/aljazceru/opencode.git
synced 2026-01-07 09:54:56 +01:00
wip: refactoring tui
This commit is contained in:
@@ -1,17 +1,13 @@
|
||||
package chat
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/charmbracelet/x/ansi"
|
||||
"github.com/sst/opencode/internal/config"
|
||||
"github.com/sst/opencode/internal/diff"
|
||||
"github.com/sst/opencode/internal/llm/tools"
|
||||
"github.com/sst/opencode/internal/message"
|
||||
"github.com/sst/opencode/internal/tui/styles"
|
||||
"github.com/sst/opencode/internal/tui/theme"
|
||||
@@ -274,25 +270,25 @@ func renderToolAction(name string) string {
|
||||
switch name {
|
||||
// case agent.AgentToolName:
|
||||
// return "Preparing prompt..."
|
||||
case tools.BashToolName:
|
||||
case "bash":
|
||||
return "Building command..."
|
||||
case tools.EditToolName:
|
||||
case "edit":
|
||||
return "Preparing edit..."
|
||||
case tools.FetchToolName:
|
||||
case "fetch":
|
||||
return "Writing fetch..."
|
||||
case tools.GlobToolName:
|
||||
case "glob":
|
||||
return "Finding files..."
|
||||
case tools.GrepToolName:
|
||||
case "grep":
|
||||
return "Searching content..."
|
||||
case tools.LSToolName:
|
||||
case "ls":
|
||||
return "Listing directory..."
|
||||
case tools.ViewToolName:
|
||||
case "view":
|
||||
return "Reading file..."
|
||||
case tools.WriteToolName:
|
||||
case "write":
|
||||
return "Preparing write..."
|
||||
case tools.PatchToolName:
|
||||
case "patch":
|
||||
return "Preparing patch..."
|
||||
case tools.BatchToolName:
|
||||
case "batch":
|
||||
return "Running batch operations..."
|
||||
}
|
||||
return "Working..."
|
||||
@@ -361,94 +357,94 @@ func removeWorkingDirPrefix(path string) string {
|
||||
func renderToolParams(paramWidth int, toolCall message.ToolCall) string {
|
||||
params := ""
|
||||
switch toolCall.Name {
|
||||
// case agent.AgentToolName:
|
||||
// var params agent.AgentParams
|
||||
// // case agent.AgentToolName:
|
||||
// // var params agent.AgentParams
|
||||
// // json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
// // prompt := strings.ReplaceAll(params.Prompt, "\n", " ")
|
||||
// // return renderParams(paramWidth, prompt)
|
||||
// case "bash":
|
||||
// var params tools.BashParams
|
||||
// json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
// prompt := strings.ReplaceAll(params.Prompt, "\n", " ")
|
||||
// return renderParams(paramWidth, prompt)
|
||||
case tools.BashToolName:
|
||||
var params tools.BashParams
|
||||
json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
command := strings.ReplaceAll(params.Command, "\n", " ")
|
||||
return renderParams(paramWidth, command)
|
||||
case tools.EditToolName:
|
||||
var params tools.EditParams
|
||||
json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
filePath := removeWorkingDirPrefix(params.FilePath)
|
||||
return renderParams(paramWidth, filePath)
|
||||
case tools.FetchToolName:
|
||||
var params tools.FetchParams
|
||||
json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
url := params.URL
|
||||
toolParams := []string{
|
||||
url,
|
||||
}
|
||||
if params.Format != "" {
|
||||
toolParams = append(toolParams, "format", params.Format)
|
||||
}
|
||||
if params.Timeout != 0 {
|
||||
toolParams = append(toolParams, "timeout", (time.Duration(params.Timeout) * time.Second).String())
|
||||
}
|
||||
return renderParams(paramWidth, toolParams...)
|
||||
case tools.GlobToolName:
|
||||
var params tools.GlobParams
|
||||
json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
pattern := params.Pattern
|
||||
toolParams := []string{
|
||||
pattern,
|
||||
}
|
||||
if params.Path != "" {
|
||||
toolParams = append(toolParams, "path", params.Path)
|
||||
}
|
||||
return renderParams(paramWidth, toolParams...)
|
||||
case tools.GrepToolName:
|
||||
var params tools.GrepParams
|
||||
json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
pattern := params.Pattern
|
||||
toolParams := []string{
|
||||
pattern,
|
||||
}
|
||||
if params.Path != "" {
|
||||
toolParams = append(toolParams, "path", params.Path)
|
||||
}
|
||||
if params.Include != "" {
|
||||
toolParams = append(toolParams, "include", params.Include)
|
||||
}
|
||||
if params.LiteralText {
|
||||
toolParams = append(toolParams, "literal", "true")
|
||||
}
|
||||
return renderParams(paramWidth, toolParams...)
|
||||
case tools.LSToolName:
|
||||
var params tools.LSParams
|
||||
json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
path := params.Path
|
||||
if path == "" {
|
||||
path = "."
|
||||
}
|
||||
return renderParams(paramWidth, path)
|
||||
case tools.ViewToolName:
|
||||
var params tools.ViewParams
|
||||
json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
filePath := removeWorkingDirPrefix(params.FilePath)
|
||||
toolParams := []string{
|
||||
filePath,
|
||||
}
|
||||
if params.Limit != 0 {
|
||||
toolParams = append(toolParams, "limit", fmt.Sprintf("%d", params.Limit))
|
||||
}
|
||||
if params.Offset != 0 {
|
||||
toolParams = append(toolParams, "offset", fmt.Sprintf("%d", params.Offset))
|
||||
}
|
||||
return renderParams(paramWidth, toolParams...)
|
||||
case tools.WriteToolName:
|
||||
var params tools.WriteParams
|
||||
json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
filePath := removeWorkingDirPrefix(params.FilePath)
|
||||
return renderParams(paramWidth, filePath)
|
||||
case tools.BatchToolName:
|
||||
var params tools.BatchParams
|
||||
json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
return renderParams(paramWidth, fmt.Sprintf("%d parallel calls", len(params.Calls)))
|
||||
// command := strings.ReplaceAll(params.Command, "\n", " ")
|
||||
// return renderParams(paramWidth, command)
|
||||
// case "edit":
|
||||
// var params tools.EditParams
|
||||
// json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
// filePath := removeWorkingDirPrefix(params.FilePath)
|
||||
// return renderParams(paramWidth, filePath)
|
||||
// case "fetch":
|
||||
// var params tools.FetchParams
|
||||
// json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
// url := params.URL
|
||||
// toolParams := []string{
|
||||
// url,
|
||||
// }
|
||||
// if params.Format != "" {
|
||||
// toolParams = append(toolParams, "format", params.Format)
|
||||
// }
|
||||
// if params.Timeout != 0 {
|
||||
// toolParams = append(toolParams, "timeout", (time.Duration(params.Timeout) * time.Second).String())
|
||||
// }
|
||||
// return renderParams(paramWidth, toolParams...)
|
||||
// case tools.GlobToolName:
|
||||
// var params tools.GlobParams
|
||||
// json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
// pattern := params.Pattern
|
||||
// toolParams := []string{
|
||||
// pattern,
|
||||
// }
|
||||
// if params.Path != "" {
|
||||
// toolParams = append(toolParams, "path", params.Path)
|
||||
// }
|
||||
// return renderParams(paramWidth, toolParams...)
|
||||
// case tools.GrepToolName:
|
||||
// var params tools.GrepParams
|
||||
// json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
// pattern := params.Pattern
|
||||
// toolParams := []string{
|
||||
// pattern,
|
||||
// }
|
||||
// if params.Path != "" {
|
||||
// toolParams = append(toolParams, "path", params.Path)
|
||||
// }
|
||||
// if params.Include != "" {
|
||||
// toolParams = append(toolParams, "include", params.Include)
|
||||
// }
|
||||
// if params.LiteralText {
|
||||
// toolParams = append(toolParams, "literal", "true")
|
||||
// }
|
||||
// return renderParams(paramWidth, toolParams...)
|
||||
// case tools.LSToolName:
|
||||
// var params tools.LSParams
|
||||
// json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
// path := params.Path
|
||||
// if path == "" {
|
||||
// path = "."
|
||||
// }
|
||||
// return renderParams(paramWidth, path)
|
||||
// case tools.ViewToolName:
|
||||
// var params tools.ViewParams
|
||||
// json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
// filePath := removeWorkingDirPrefix(params.FilePath)
|
||||
// toolParams := []string{
|
||||
// filePath,
|
||||
// }
|
||||
// if params.Limit != 0 {
|
||||
// toolParams = append(toolParams, "limit", fmt.Sprintf("%d", params.Limit))
|
||||
// }
|
||||
// if params.Offset != 0 {
|
||||
// toolParams = append(toolParams, "offset", fmt.Sprintf("%d", params.Offset))
|
||||
// }
|
||||
// return renderParams(paramWidth, toolParams...)
|
||||
// case tools.WriteToolName:
|
||||
// var params tools.WriteParams
|
||||
// json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
// filePath := removeWorkingDirPrefix(params.FilePath)
|
||||
// return renderParams(paramWidth, filePath)
|
||||
// case tools.BatchToolName:
|
||||
// var params tools.BatchParams
|
||||
// json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
// return renderParams(paramWidth, fmt.Sprintf("%d parallel calls", len(params.Calls)))
|
||||
default:
|
||||
input := strings.ReplaceAll(toolCall.Input, "\n", " ")
|
||||
params = renderParams(paramWidth, input)
|
||||
@@ -484,100 +480,100 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
|
||||
// toMarkdown(resultContent, false, width),
|
||||
// t.Background(),
|
||||
// )
|
||||
case tools.BashToolName:
|
||||
resultContent = fmt.Sprintf("```bash\n%s\n```", resultContent)
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
toMarkdown(resultContent, width),
|
||||
t.Background(),
|
||||
)
|
||||
case tools.EditToolName:
|
||||
metadata := tools.EditResponseMetadata{}
|
||||
json.Unmarshal([]byte(response.Metadata), &metadata)
|
||||
formattedDiff, _ := diff.FormatDiff(metadata.Diff, diff.WithTotalWidth(width))
|
||||
return formattedDiff
|
||||
case tools.FetchToolName:
|
||||
var params tools.FetchParams
|
||||
json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
mdFormat := "markdown"
|
||||
switch params.Format {
|
||||
case "text":
|
||||
mdFormat = "text"
|
||||
case "html":
|
||||
mdFormat = "html"
|
||||
}
|
||||
resultContent = fmt.Sprintf("```%s\n%s\n```", mdFormat, resultContent)
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
toMarkdown(resultContent, width),
|
||||
t.Background(),
|
||||
)
|
||||
case tools.GlobToolName:
|
||||
return baseStyle.Width(width).Foreground(t.TextMuted()).Render(resultContent)
|
||||
case tools.GrepToolName:
|
||||
return baseStyle.Width(width).Foreground(t.TextMuted()).Render(resultContent)
|
||||
case tools.LSToolName:
|
||||
return baseStyle.Width(width).Foreground(t.TextMuted()).Render(resultContent)
|
||||
case tools.ViewToolName:
|
||||
metadata := tools.ViewResponseMetadata{}
|
||||
json.Unmarshal([]byte(response.Metadata), &metadata)
|
||||
ext := filepath.Ext(metadata.FilePath)
|
||||
if ext == "" {
|
||||
ext = ""
|
||||
} else {
|
||||
ext = strings.ToLower(ext[1:])
|
||||
}
|
||||
resultContent = fmt.Sprintf("```%s\n%s\n```", ext, truncateHeight(metadata.Content, maxResultHeight))
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
toMarkdown(resultContent, width),
|
||||
t.Background(),
|
||||
)
|
||||
case tools.WriteToolName:
|
||||
params := tools.WriteParams{}
|
||||
json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
metadata := tools.WriteResponseMetadata{}
|
||||
json.Unmarshal([]byte(response.Metadata), &metadata)
|
||||
ext := filepath.Ext(params.FilePath)
|
||||
if ext == "" {
|
||||
ext = ""
|
||||
} else {
|
||||
ext = strings.ToLower(ext[1:])
|
||||
}
|
||||
resultContent = fmt.Sprintf("```%s\n%s\n```", ext, truncateHeight(params.Content, maxResultHeight))
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
toMarkdown(resultContent, width),
|
||||
t.Background(),
|
||||
)
|
||||
case tools.BatchToolName:
|
||||
var batchResult tools.BatchResult
|
||||
if err := json.Unmarshal([]byte(resultContent), &batchResult); err != nil {
|
||||
return baseStyle.Width(width).Foreground(t.Error()).Render(fmt.Sprintf("Error parsing batch result: %s", err))
|
||||
}
|
||||
|
||||
var toolCalls []string
|
||||
for i, result := range batchResult.Results {
|
||||
toolName := renderToolName(result.ToolName)
|
||||
|
||||
// Format the tool input as a string
|
||||
inputStr := string(result.ToolInput)
|
||||
|
||||
// Format the result
|
||||
var resultStr string
|
||||
if result.Error != "" {
|
||||
resultStr = fmt.Sprintf("Error: %s", result.Error)
|
||||
} else {
|
||||
var toolResponse tools.ToolResponse
|
||||
if err := json.Unmarshal(result.Result, &toolResponse); err != nil {
|
||||
resultStr = "Error parsing tool response"
|
||||
} else {
|
||||
resultStr = truncateHeight(toolResponse.Content, 3)
|
||||
}
|
||||
}
|
||||
|
||||
// Format the tool call
|
||||
toolCall := fmt.Sprintf("%d. %s: %s\n %s", i+1, toolName, inputStr, resultStr)
|
||||
toolCalls = append(toolCalls, toolCall)
|
||||
}
|
||||
|
||||
return baseStyle.Width(width).Foreground(t.TextMuted()).Render(strings.Join(toolCalls, "\n\n"))
|
||||
// case tools.BashToolName:
|
||||
// resultContent = fmt.Sprintf("```bash\n%s\n```", resultContent)
|
||||
// return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
// toMarkdown(resultContent, width),
|
||||
// t.Background(),
|
||||
// )
|
||||
// case tools.EditToolName:
|
||||
// metadata := tools.EditResponseMetadata{}
|
||||
// json.Unmarshal([]byte(response.Metadata), &metadata)
|
||||
// formattedDiff, _ := diff.FormatDiff(metadata.Diff, diff.WithTotalWidth(width))
|
||||
// return formattedDiff
|
||||
// case tools.FetchToolName:
|
||||
// var params tools.FetchParams
|
||||
// json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
// mdFormat := "markdown"
|
||||
// switch params.Format {
|
||||
// case "text":
|
||||
// mdFormat = "text"
|
||||
// case "html":
|
||||
// mdFormat = "html"
|
||||
// }
|
||||
// resultContent = fmt.Sprintf("```%s\n%s\n```", mdFormat, resultContent)
|
||||
// return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
// toMarkdown(resultContent, width),
|
||||
// t.Background(),
|
||||
// )
|
||||
// case tools.GlobToolName:
|
||||
// return baseStyle.Width(width).Foreground(t.TextMuted()).Render(resultContent)
|
||||
// case tools.GrepToolName:
|
||||
// return baseStyle.Width(width).Foreground(t.TextMuted()).Render(resultContent)
|
||||
// case tools.LSToolName:
|
||||
// return baseStyle.Width(width).Foreground(t.TextMuted()).Render(resultContent)
|
||||
// case tools.ViewToolName:
|
||||
// metadata := tools.ViewResponseMetadata{}
|
||||
// json.Unmarshal([]byte(response.Metadata), &metadata)
|
||||
// ext := filepath.Ext(metadata.FilePath)
|
||||
// if ext == "" {
|
||||
// ext = ""
|
||||
// } else {
|
||||
// ext = strings.ToLower(ext[1:])
|
||||
// }
|
||||
// resultContent = fmt.Sprintf("```%s\n%s\n```", ext, truncateHeight(metadata.Content, maxResultHeight))
|
||||
// return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
// toMarkdown(resultContent, width),
|
||||
// t.Background(),
|
||||
// )
|
||||
// case tools.WriteToolName:
|
||||
// params := tools.WriteParams{}
|
||||
// json.Unmarshal([]byte(toolCall.Input), ¶ms)
|
||||
// metadata := tools.WriteResponseMetadata{}
|
||||
// json.Unmarshal([]byte(response.Metadata), &metadata)
|
||||
// ext := filepath.Ext(params.FilePath)
|
||||
// if ext == "" {
|
||||
// ext = ""
|
||||
// } else {
|
||||
// ext = strings.ToLower(ext[1:])
|
||||
// }
|
||||
// resultContent = fmt.Sprintf("```%s\n%s\n```", ext, truncateHeight(params.Content, maxResultHeight))
|
||||
// return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
// toMarkdown(resultContent, width),
|
||||
// t.Background(),
|
||||
// )
|
||||
// case tools.BatchToolName:
|
||||
// var batchResult tools.BatchResult
|
||||
// if err := json.Unmarshal([]byte(resultContent), &batchResult); err != nil {
|
||||
// return baseStyle.Width(width).Foreground(t.Error()).Render(fmt.Sprintf("Error parsing batch result: %s", err))
|
||||
// }
|
||||
//
|
||||
// var toolCalls []string
|
||||
// for i, result := range batchResult.Results {
|
||||
// toolName := renderToolName(result.ToolName)
|
||||
//
|
||||
// // Format the tool input as a string
|
||||
// inputStr := string(result.ToolInput)
|
||||
//
|
||||
// // Format the result
|
||||
// var resultStr string
|
||||
// if result.Error != "" {
|
||||
// resultStr = fmt.Sprintf("Error: %s", result.Error)
|
||||
// } else {
|
||||
// var toolResponse tools.ToolResponse
|
||||
// if err := json.Unmarshal(result.Result, &toolResponse); err != nil {
|
||||
// resultStr = "Error parsing tool response"
|
||||
// } else {
|
||||
// resultStr = truncateHeight(toolResponse.Content, 3)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Format the tool call
|
||||
// toolCall := fmt.Sprintf("%d. %s: %s\n %s", i+1, toolName, inputStr, resultStr)
|
||||
// toolCalls = append(toolCalls, toolCall)
|
||||
// }
|
||||
//
|
||||
// return baseStyle.Width(width).Foreground(t.TextMuted()).Render(strings.Join(toolCalls, "\n\n"))
|
||||
default:
|
||||
resultContent = fmt.Sprintf("```text\n%s\n```", resultContent)
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
|
||||
@@ -7,9 +7,6 @@ import (
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/sst/opencode/internal/config"
|
||||
"github.com/sst/opencode/internal/llm/models"
|
||||
"github.com/sst/opencode/internal/lsp/protocol"
|
||||
"github.com/sst/opencode/internal/pubsub"
|
||||
"github.com/sst/opencode/internal/status"
|
||||
"github.com/sst/opencode/internal/tui/app"
|
||||
@@ -148,20 +145,20 @@ func formatTokensAndCost(tokens int64, contextWindow int64, cost float64) string
|
||||
|
||||
func (m statusCmp) View() string {
|
||||
t := theme.CurrentTheme()
|
||||
modelID := config.Get().Agents[config.AgentPrimary].Model
|
||||
model := models.SupportedModels[modelID]
|
||||
// modelID := config.Get().Agents[config.AgentPrimary].Model
|
||||
// model := models.SupportedModels[modelID]
|
||||
|
||||
// Initialize the help widget
|
||||
status := getHelpWidget("")
|
||||
|
||||
if m.app.CurrentSessionOLD.ID != "" {
|
||||
tokens := formatTokensAndCost(m.app.CurrentSessionOLD.PromptTokens+m.app.CurrentSessionOLD.CompletionTokens, model.ContextWindow, m.app.CurrentSessionOLD.Cost)
|
||||
tokensStyle := styles.Padded().
|
||||
Background(t.Text()).
|
||||
Foreground(t.BackgroundSecondary()).
|
||||
Render(tokens)
|
||||
status += tokensStyle
|
||||
}
|
||||
// if m.app.CurrentSessionOLD.ID != "" {
|
||||
// tokens := formatTokensAndCost(m.app.CurrentSessionOLD.PromptTokens+m.app.CurrentSessionOLD.CompletionTokens, model.ContextWindow, m.app.CurrentSessionOLD.Cost)
|
||||
// tokensStyle := styles.Padded().
|
||||
// Background(t.Text()).
|
||||
// Foreground(t.BackgroundSecondary()).
|
||||
// Render(tokens)
|
||||
// status += tokensStyle
|
||||
// }
|
||||
|
||||
diagnostics := styles.Padded().Background(t.BackgroundDarker()).Render(m.projectDiagnostics())
|
||||
|
||||
@@ -258,10 +255,10 @@ func (m *statusCmp) projectDiagnostics() string {
|
||||
Render(fmt.Sprintf("%s Initializing LSP...", styles.SpinnerIcon))
|
||||
}
|
||||
|
||||
errorDiagnostics := []protocol.Diagnostic{}
|
||||
warnDiagnostics := []protocol.Diagnostic{}
|
||||
hintDiagnostics := []protocol.Diagnostic{}
|
||||
infoDiagnostics := []protocol.Diagnostic{}
|
||||
// errorDiagnostics := []protocol.Diagnostic{}
|
||||
// warnDiagnostics := []protocol.Diagnostic{}
|
||||
// hintDiagnostics := []protocol.Diagnostic{}
|
||||
// infoDiagnostics := []protocol.Diagnostic{}
|
||||
// for _, client := range m.app.LSPClients {
|
||||
// for _, d := range client.GetDiagnostics() {
|
||||
// for _, diag := range d {
|
||||
@@ -278,64 +275,61 @@ func (m *statusCmp) projectDiagnostics() string {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if len(errorDiagnostics) == 0 &&
|
||||
len(warnDiagnostics) == 0 &&
|
||||
len(infoDiagnostics) == 0 &&
|
||||
len(hintDiagnostics) == 0 {
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
styles.Padded().Render("No diagnostics"),
|
||||
t.BackgroundDarker(),
|
||||
)
|
||||
}
|
||||
|
||||
diagnostics := []string{}
|
||||
|
||||
errStr := lipgloss.NewStyle().
|
||||
Background(t.BackgroundDarker()).
|
||||
Foreground(t.Error()).
|
||||
Render(fmt.Sprintf("%s %d", styles.ErrorIcon, len(errorDiagnostics)))
|
||||
diagnostics = append(diagnostics, errStr)
|
||||
|
||||
warnStr := lipgloss.NewStyle().
|
||||
Background(t.BackgroundDarker()).
|
||||
Foreground(t.Warning()).
|
||||
Render(fmt.Sprintf("%s %d", styles.WarningIcon, len(warnDiagnostics)))
|
||||
diagnostics = append(diagnostics, warnStr)
|
||||
|
||||
infoStr := lipgloss.NewStyle().
|
||||
Background(t.BackgroundDarker()).
|
||||
Foreground(t.Info()).
|
||||
Render(fmt.Sprintf("%s %d", styles.InfoIcon, len(infoDiagnostics)))
|
||||
diagnostics = append(diagnostics, infoStr)
|
||||
|
||||
hintStr := lipgloss.NewStyle().
|
||||
Background(t.BackgroundDarker()).
|
||||
Foreground(t.Text()).
|
||||
Render(fmt.Sprintf("%s %d", styles.HintIcon, len(hintDiagnostics)))
|
||||
diagnostics = append(diagnostics, hintStr)
|
||||
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
styles.Padded().Render(strings.Join(diagnostics, " ")),
|
||||
styles.Padded().Render("No diagnostics"),
|
||||
t.BackgroundDarker(),
|
||||
)
|
||||
|
||||
// if len(errorDiagnostics) == 0 &&
|
||||
// len(warnDiagnostics) == 0 &&
|
||||
// len(infoDiagnostics) == 0 &&
|
||||
// len(hintDiagnostics) == 0 {
|
||||
// return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
// styles.Padded().Render("No diagnostics"),
|
||||
// t.BackgroundDarker(),
|
||||
// )
|
||||
// }
|
||||
|
||||
// diagnostics := []string{}
|
||||
//
|
||||
// errStr := lipgloss.NewStyle().
|
||||
// Background(t.BackgroundDarker()).
|
||||
// Foreground(t.Error()).
|
||||
// Render(fmt.Sprintf("%s %d", styles.ErrorIcon, len(errorDiagnostics)))
|
||||
// diagnostics = append(diagnostics, errStr)
|
||||
//
|
||||
// warnStr := lipgloss.NewStyle().
|
||||
// Background(t.BackgroundDarker()).
|
||||
// Foreground(t.Warning()).
|
||||
// Render(fmt.Sprintf("%s %d", styles.WarningIcon, len(warnDiagnostics)))
|
||||
// diagnostics = append(diagnostics, warnStr)
|
||||
//
|
||||
// infoStr := lipgloss.NewStyle().
|
||||
// Background(t.BackgroundDarker()).
|
||||
// Foreground(t.Info()).
|
||||
// Render(fmt.Sprintf("%s %d", styles.InfoIcon, len(infoDiagnostics)))
|
||||
// diagnostics = append(diagnostics, infoStr)
|
||||
//
|
||||
// hintStr := lipgloss.NewStyle().
|
||||
// Background(t.BackgroundDarker()).
|
||||
// Foreground(t.Text()).
|
||||
// Render(fmt.Sprintf("%s %d", styles.HintIcon, len(hintDiagnostics)))
|
||||
// diagnostics = append(diagnostics, hintStr)
|
||||
//
|
||||
// return styles.ForceReplaceBackgroundWithLipgloss(
|
||||
// styles.Padded().Render(strings.Join(diagnostics, " ")),
|
||||
// t.BackgroundDarker(),
|
||||
// )
|
||||
}
|
||||
|
||||
func (m statusCmp) model() string {
|
||||
t := theme.CurrentTheme()
|
||||
|
||||
cfg := config.Get()
|
||||
|
||||
coder, ok := cfg.Agents[config.AgentPrimary]
|
||||
if !ok {
|
||||
return "Unknown"
|
||||
}
|
||||
model := models.SupportedModels[coder.Model]
|
||||
model := "Claude Sonnet 4" // models.SupportedModels[coder.Model]
|
||||
|
||||
return styles.Padded().
|
||||
Background(t.Secondary()).
|
||||
Foreground(t.Background()).
|
||||
Render(model.Name)
|
||||
Render(model)
|
||||
}
|
||||
|
||||
func (m statusCmp) SetHelpWidgetMsg(s string) {
|
||||
|
||||
@@ -7,8 +7,6 @@ import (
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/sst/opencode/internal/config"
|
||||
"github.com/sst/opencode/internal/diff"
|
||||
"github.com/sst/opencode/internal/llm/tools"
|
||||
"github.com/sst/opencode/internal/permission"
|
||||
"github.com/sst/opencode/internal/tui/layout"
|
||||
"github.com/sst/opencode/internal/tui/styles"
|
||||
@@ -206,7 +204,7 @@ func (p *permissionDialogCmp) renderHeader() string {
|
||||
Render(fmt.Sprintf(": %s", p.permission.ToolName))
|
||||
|
||||
pathKey := baseStyle.Foreground(t.TextMuted()).Bold(true).Render("Path")
|
||||
|
||||
|
||||
// Get the current working directory to display relative path
|
||||
relativePath := p.permission.Path
|
||||
if filepath.IsAbs(relativePath) {
|
||||
@@ -214,7 +212,7 @@ func (p *permissionDialogCmp) renderHeader() string {
|
||||
relativePath = cwd
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pathValue := baseStyle.
|
||||
Foreground(t.Text()).
|
||||
Width(p.width - lipgloss.Width(pathKey)).
|
||||
@@ -237,13 +235,13 @@ func (p *permissionDialogCmp) renderHeader() string {
|
||||
|
||||
// Add tool-specific header information
|
||||
switch p.permission.ToolName {
|
||||
case tools.BashToolName:
|
||||
case "bash":
|
||||
headerParts = append(headerParts, baseStyle.Foreground(t.TextMuted()).Width(p.width).Bold(true).Render("Command"))
|
||||
case tools.EditToolName:
|
||||
case "edit":
|
||||
headerParts = append(headerParts, baseStyle.Foreground(t.TextMuted()).Width(p.width).Bold(true).Render("Diff"))
|
||||
case tools.WriteToolName:
|
||||
case "write":
|
||||
headerParts = append(headerParts, baseStyle.Foreground(t.TextMuted()).Width(p.width).Bold(true).Render("Diff"))
|
||||
case tools.FetchToolName:
|
||||
case "fetch":
|
||||
headerParts = append(headerParts, baseStyle.Foreground(t.TextMuted()).Width(p.width).Bold(true).Render("URL"))
|
||||
}
|
||||
|
||||
@@ -251,110 +249,110 @@ func (p *permissionDialogCmp) renderHeader() string {
|
||||
}
|
||||
|
||||
func (p *permissionDialogCmp) renderBashContent() string {
|
||||
t := theme.CurrentTheme()
|
||||
baseStyle := styles.BaseStyle()
|
||||
|
||||
if pr, ok := p.permission.Params.(tools.BashPermissionsParams); ok {
|
||||
content := fmt.Sprintf("```bash\n%s\n```", pr.Command)
|
||||
|
||||
// Use the cache for markdown rendering
|
||||
renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
|
||||
r := styles.GetMarkdownRenderer(p.width - 10)
|
||||
s, err := r.Render(content)
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
|
||||
})
|
||||
|
||||
finalContent := baseStyle.
|
||||
Width(p.contentViewPort.Width).
|
||||
Render(renderedContent)
|
||||
p.contentViewPort.SetContent(finalContent)
|
||||
return p.styleViewport()
|
||||
}
|
||||
// t := theme.CurrentTheme()
|
||||
// baseStyle := styles.BaseStyle()
|
||||
//
|
||||
// if pr, ok := p.permission.Params.(tools.BashPermissionsParams); ok {
|
||||
// content := fmt.Sprintf("```bash\n%s\n```", pr.Command)
|
||||
//
|
||||
// // Use the cache for markdown rendering
|
||||
// renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
|
||||
// r := styles.GetMarkdownRenderer(p.width - 10)
|
||||
// s, err := r.Render(content)
|
||||
// return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
|
||||
// })
|
||||
//
|
||||
// finalContent := baseStyle.
|
||||
// Width(p.contentViewPort.Width).
|
||||
// Render(renderedContent)
|
||||
// p.contentViewPort.SetContent(finalContent)
|
||||
// return p.styleViewport()
|
||||
// }
|
||||
return ""
|
||||
}
|
||||
|
||||
func (p *permissionDialogCmp) renderEditContent() string {
|
||||
if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
|
||||
diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
|
||||
return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
|
||||
})
|
||||
|
||||
p.contentViewPort.SetContent(diff)
|
||||
return p.styleViewport()
|
||||
}
|
||||
// if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
|
||||
// diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
|
||||
// return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
|
||||
// })
|
||||
//
|
||||
// p.contentViewPort.SetContent(diff)
|
||||
// return p.styleViewport()
|
||||
// }
|
||||
return ""
|
||||
}
|
||||
|
||||
func (p *permissionDialogCmp) renderPatchContent() string {
|
||||
if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
|
||||
diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
|
||||
return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
|
||||
})
|
||||
|
||||
p.contentViewPort.SetContent(diff)
|
||||
return p.styleViewport()
|
||||
}
|
||||
// if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
|
||||
// diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
|
||||
// return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
|
||||
// })
|
||||
//
|
||||
// p.contentViewPort.SetContent(diff)
|
||||
// return p.styleViewport()
|
||||
// }
|
||||
return ""
|
||||
}
|
||||
|
||||
func (p *permissionDialogCmp) renderWriteContent() string {
|
||||
if pr, ok := p.permission.Params.(tools.WritePermissionsParams); ok {
|
||||
// Use the cache for diff rendering
|
||||
diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
|
||||
return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
|
||||
})
|
||||
|
||||
p.contentViewPort.SetContent(diff)
|
||||
return p.styleViewport()
|
||||
}
|
||||
// if pr, ok := p.permission.Params.(tools.WritePermissionsParams); ok {
|
||||
// // Use the cache for diff rendering
|
||||
// diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
|
||||
// return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
|
||||
// })
|
||||
//
|
||||
// p.contentViewPort.SetContent(diff)
|
||||
// return p.styleViewport()
|
||||
// }
|
||||
return ""
|
||||
}
|
||||
|
||||
func (p *permissionDialogCmp) renderFetchContent() string {
|
||||
t := theme.CurrentTheme()
|
||||
baseStyle := styles.BaseStyle()
|
||||
|
||||
if pr, ok := p.permission.Params.(tools.FetchPermissionsParams); ok {
|
||||
content := fmt.Sprintf("```bash\n%s\n```", pr.URL)
|
||||
|
||||
// Use the cache for markdown rendering
|
||||
renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
|
||||
r := styles.GetMarkdownRenderer(p.width - 10)
|
||||
s, err := r.Render(content)
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
|
||||
})
|
||||
|
||||
finalContent := baseStyle.
|
||||
Width(p.contentViewPort.Width).
|
||||
Render(renderedContent)
|
||||
p.contentViewPort.SetContent(finalContent)
|
||||
return p.styleViewport()
|
||||
}
|
||||
// t := theme.CurrentTheme()
|
||||
// baseStyle := styles.BaseStyle()
|
||||
//
|
||||
// if pr, ok := p.permission.Params.(tools.FetchPermissionsParams); ok {
|
||||
// content := fmt.Sprintf("```bash\n%s\n```", pr.URL)
|
||||
//
|
||||
// // Use the cache for markdown rendering
|
||||
// renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
|
||||
// r := styles.GetMarkdownRenderer(p.width - 10)
|
||||
// s, err := r.Render(content)
|
||||
// return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
|
||||
// })
|
||||
//
|
||||
// finalContent := baseStyle.
|
||||
// Width(p.contentViewPort.Width).
|
||||
// Render(renderedContent)
|
||||
// p.contentViewPort.SetContent(finalContent)
|
||||
// return p.styleViewport()
|
||||
// }
|
||||
return ""
|
||||
}
|
||||
|
||||
func (p *permissionDialogCmp) renderDefaultContent() string {
|
||||
t := theme.CurrentTheme()
|
||||
baseStyle := styles.BaseStyle()
|
||||
|
||||
content := p.permission.Description
|
||||
|
||||
// Use the cache for markdown rendering
|
||||
renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
|
||||
r := styles.GetMarkdownRenderer(p.width - 10)
|
||||
s, err := r.Render(content)
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
|
||||
})
|
||||
|
||||
finalContent := baseStyle.
|
||||
Width(p.contentViewPort.Width).
|
||||
Render(renderedContent)
|
||||
p.contentViewPort.SetContent(finalContent)
|
||||
|
||||
if renderedContent == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// t := theme.CurrentTheme()
|
||||
// baseStyle := styles.BaseStyle()
|
||||
//
|
||||
// content := p.permission.Description
|
||||
//
|
||||
// // Use the cache for markdown rendering
|
||||
// renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
|
||||
// r := styles.GetMarkdownRenderer(p.width - 10)
|
||||
// s, err := r.Render(content)
|
||||
// return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
|
||||
// })
|
||||
//
|
||||
// finalContent := baseStyle.
|
||||
// Width(p.contentViewPort.Width).
|
||||
// Render(renderedContent)
|
||||
// p.contentViewPort.SetContent(finalContent)
|
||||
//
|
||||
// if renderedContent == "" {
|
||||
// return ""
|
||||
// }
|
||||
//
|
||||
return p.styleViewport()
|
||||
}
|
||||
|
||||
@@ -387,15 +385,15 @@ func (p *permissionDialogCmp) render() string {
|
||||
// Render content based on tool type
|
||||
var contentFinal string
|
||||
switch p.permission.ToolName {
|
||||
case tools.BashToolName:
|
||||
case "bash":
|
||||
contentFinal = p.renderBashContent()
|
||||
case tools.EditToolName:
|
||||
case "edit":
|
||||
contentFinal = p.renderEditContent()
|
||||
case tools.PatchToolName:
|
||||
case "patch":
|
||||
contentFinal = p.renderPatchContent()
|
||||
case tools.WriteToolName:
|
||||
case "write":
|
||||
contentFinal = p.renderWriteContent()
|
||||
case tools.FetchToolName:
|
||||
case "fetch":
|
||||
contentFinal = p.renderFetchContent()
|
||||
default:
|
||||
contentFinal = p.renderDefaultContent()
|
||||
@@ -436,16 +434,16 @@ func (p *permissionDialogCmp) SetSize() tea.Cmd {
|
||||
return nil
|
||||
}
|
||||
switch p.permission.ToolName {
|
||||
case tools.BashToolName:
|
||||
case "bash":
|
||||
p.width = int(float64(p.windowSize.Width) * 0.4)
|
||||
p.height = int(float64(p.windowSize.Height) * 0.3)
|
||||
case tools.EditToolName:
|
||||
case "edit":
|
||||
p.width = int(float64(p.windowSize.Width) * 0.8)
|
||||
p.height = int(float64(p.windowSize.Height) * 0.8)
|
||||
case tools.WriteToolName:
|
||||
case "write":
|
||||
p.width = int(float64(p.windowSize.Width) * 0.8)
|
||||
p.height = int(float64(p.windowSize.Height) * 0.8)
|
||||
case tools.FetchToolName:
|
||||
case "fetch":
|
||||
p.width = int(float64(p.windowSize.Width) * 0.4)
|
||||
p.height = int(float64(p.windowSize.Height) * 0.3)
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user