Browse Source

wip: refactoring tui

adamdottv 9 months ago
parent
commit
8a8c6b14af
3 changed files with 163 additions and 412 deletions
  1. 0 246
      internal/permission/permission.go
  2. 160 161
      internal/tui/components/dialog/permission.go
  3. 3 5
      internal/tui/tui.go

+ 0 - 246
internal/permission/permission.go

@@ -1,246 +0,0 @@
-package permission
-
-import (
-	"context"
-	"errors"
-	"fmt"
-	"path/filepath"
-	"strings"
-	"sync"
-
-	"log/slog"
-
-	"github.com/google/uuid"
-	"github.com/sst/opencode/internal/config"
-	"github.com/sst/opencode/internal/pubsub"
-)
-
-var ErrorPermissionDenied = errors.New("permission denied")
-
-type CreatePermissionRequest struct {
-	SessionID   string `json:"session_id"`
-	ToolName    string `json:"tool_name"`
-	Description string `json:"description"`
-	Action      string `json:"action"`
-	Params      any    `json:"params"`
-	Path        string `json:"path"`
-}
-
-type PermissionRequest struct {
-	ID          string `json:"id"`
-	SessionID   string `json:"session_id"`
-	ToolName    string `json:"tool_name"`
-	Description string `json:"description"`
-	Action      string `json:"action"`
-	Params      any    `json:"params"`
-	Path        string `json:"path"`
-}
-
-type PermissionResponse struct {
-	Request PermissionRequest
-	Granted bool
-}
-
-const (
-	EventPermissionRequested pubsub.EventType = "permission_requested"
-	EventPermissionGranted   pubsub.EventType = "permission_granted"
-	EventPermissionDenied    pubsub.EventType = "permission_denied"
-	EventPermissionPersisted pubsub.EventType = "permission_persisted"
-)
-
-type Service interface {
-	pubsub.Subscriber[PermissionRequest]
-	SubscribeToResponseEvents(ctx context.Context) <-chan pubsub.Event[PermissionResponse]
-
-	GrantPersistant(ctx context.Context, permission PermissionRequest)
-	Grant(ctx context.Context, permission PermissionRequest)
-	Deny(ctx context.Context, permission PermissionRequest)
-	Request(ctx context.Context, opts CreatePermissionRequest) bool
-	AutoApproveSession(ctx context.Context, sessionID string)
-	IsAutoApproved(ctx context.Context, sessionID string) bool
-}
-
-type permissionService struct {
-	broker         *pubsub.Broker[PermissionRequest]
-	responseBroker *pubsub.Broker[PermissionResponse]
-
-	sessionPermissions  map[string][]PermissionRequest
-	pendingRequests     sync.Map
-	autoApproveSessions map[string]bool
-	mu                  sync.RWMutex
-}
-
-var globalPermissionService *permissionService
-
-func InitService() error {
-	if globalPermissionService != nil {
-		return fmt.Errorf("permission service already initialized")
-	}
-	globalPermissionService = &permissionService{
-		broker:              pubsub.NewBroker[PermissionRequest](),
-		responseBroker:      pubsub.NewBroker[PermissionResponse](),
-		sessionPermissions:  make(map[string][]PermissionRequest),
-		autoApproveSessions: make(map[string]bool),
-	}
-	return nil
-}
-
-func GetService() *permissionService {
-	if globalPermissionService == nil {
-		panic("permission service not initialized. Call permission.InitService() first.")
-	}
-	return globalPermissionService
-}
-
-func (s *permissionService) GrantPersistant(ctx context.Context, permission PermissionRequest) {
-	s.mu.Lock()
-	s.sessionPermissions[permission.SessionID] = append(s.sessionPermissions[permission.SessionID], permission)
-	s.mu.Unlock()
-
-	respCh, ok := s.pendingRequests.Load(permission.ID)
-	if ok {
-		select {
-		case respCh.(chan bool) <- true:
-		case <-ctx.Done():
-			slog.Warn("Context cancelled while sending grant persistent response", "request_id", permission.ID)
-		}
-	}
-	s.responseBroker.Publish(EventPermissionPersisted, PermissionResponse{Request: permission, Granted: true})
-}
-
-func (s *permissionService) Grant(ctx context.Context, permission PermissionRequest) {
-	respCh, ok := s.pendingRequests.Load(permission.ID)
-	if ok {
-		select {
-		case respCh.(chan bool) <- true:
-		case <-ctx.Done():
-			slog.Warn("Context cancelled while sending grant response", "request_id", permission.ID)
-		}
-	}
-	s.responseBroker.Publish(EventPermissionGranted, PermissionResponse{Request: permission, Granted: true})
-}
-
-func (s *permissionService) Deny(ctx context.Context, permission PermissionRequest) {
-	respCh, ok := s.pendingRequests.Load(permission.ID)
-	if ok {
-		select {
-		case respCh.(chan bool) <- false:
-		case <-ctx.Done():
-			slog.Warn("Context cancelled while sending deny response", "request_id", permission.ID)
-		}
-	}
-	s.responseBroker.Publish(EventPermissionDenied, PermissionResponse{Request: permission, Granted: false})
-}
-
-func (s *permissionService) Request(ctx context.Context, opts CreatePermissionRequest) bool {
-	s.mu.RLock()
-	if s.autoApproveSessions[opts.SessionID] {
-		s.mu.RUnlock()
-		return true
-	}
-
-	requestPath := opts.Path
-	if !filepath.IsAbs(requestPath) {
-		requestPath = filepath.Join(config.WorkingDirectory(), requestPath)
-	}
-	requestPath = filepath.Clean(requestPath)
-
-	if permissions, ok := s.sessionPermissions[opts.SessionID]; ok {
-		for _, p := range permissions {
-			storedPath := p.Path
-			if !filepath.IsAbs(storedPath) {
-				storedPath = filepath.Join(config.WorkingDirectory(), storedPath)
-			}
-			storedPath = filepath.Clean(storedPath)
-
-			if p.ToolName == opts.ToolName && p.Action == opts.Action &&
-				(requestPath == storedPath || strings.HasPrefix(requestPath, storedPath+string(filepath.Separator))) {
-				s.mu.RUnlock()
-				return true
-			}
-		}
-	}
-	s.mu.RUnlock()
-
-	normalizedPath := opts.Path
-	if !filepath.IsAbs(normalizedPath) {
-		normalizedPath = filepath.Join(config.WorkingDirectory(), normalizedPath)
-	}
-	normalizedPath = filepath.Clean(normalizedPath)
-
-	permissionReq := PermissionRequest{
-		ID:          uuid.New().String(),
-		Path:        normalizedPath,
-		SessionID:   opts.SessionID,
-		ToolName:    opts.ToolName,
-		Description: opts.Description,
-		Action:      opts.Action,
-		Params:      opts.Params,
-	}
-
-	respCh := make(chan bool, 1)
-	s.pendingRequests.Store(permissionReq.ID, respCh)
-	defer s.pendingRequests.Delete(permissionReq.ID)
-
-	s.broker.Publish(EventPermissionRequested, permissionReq)
-
-	select {
-	case resp := <-respCh:
-		return resp
-	case <-ctx.Done():
-		slog.Warn("Permission request timed out or context cancelled", "request_id", permissionReq.ID, "tool", opts.ToolName)
-		return false
-	}
-}
-
-func (s *permissionService) AutoApproveSession(ctx context.Context, sessionID string) {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	s.autoApproveSessions[sessionID] = true
-}
-
-func (s *permissionService) IsAutoApproved(ctx context.Context, sessionID string) bool {
-	s.mu.RLock()
-	defer s.mu.RUnlock()
-	return s.autoApproveSessions[sessionID]
-}
-
-func (s *permissionService) Subscribe(ctx context.Context) <-chan pubsub.Event[PermissionRequest] {
-	return s.broker.Subscribe(ctx)
-}
-
-func (s *permissionService) SubscribeToResponseEvents(ctx context.Context) <-chan pubsub.Event[PermissionResponse] {
-	return s.responseBroker.Subscribe(ctx)
-}
-
-func GrantPersistant(ctx context.Context, permission PermissionRequest) {
-	GetService().GrantPersistant(ctx, permission)
-}
-
-func Grant(ctx context.Context, permission PermissionRequest) {
-	GetService().Grant(ctx, permission)
-}
-
-func Deny(ctx context.Context, permission PermissionRequest) {
-	GetService().Deny(ctx, permission)
-}
-
-func Request(ctx context.Context, opts CreatePermissionRequest) bool {
-	return GetService().Request(ctx, opts)
-}
-
-func AutoApproveSession(ctx context.Context, sessionID string) {
-	GetService().AutoApproveSession(ctx, sessionID)
-}
-
-func IsAutoApproved(ctx context.Context, sessionID string) bool {
-	return GetService().IsAutoApproved(ctx, sessionID)
-}
-
-func SubscribeToRequests(ctx context.Context) <-chan pubsub.Event[PermissionRequest] {
-	return GetService().Subscribe(ctx)
-}
-
-func SubscribeToResponses(ctx context.Context) <-chan pubsub.Event[PermissionResponse] {
-	return GetService().SubscribeToResponseEvents(ctx)
-}

+ 160 - 161
internal/tui/components/dialog/permission.go

@@ -6,13 +6,10 @@ import (
 	"github.com/charmbracelet/bubbles/viewport"
 	"github.com/charmbracelet/bubbles/viewport"
 	tea "github.com/charmbracelet/bubbletea"
 	tea "github.com/charmbracelet/bubbletea"
 	"github.com/charmbracelet/lipgloss"
 	"github.com/charmbracelet/lipgloss"
-	"github.com/sst/opencode/internal/config"
-	"github.com/sst/opencode/internal/permission"
 	"github.com/sst/opencode/internal/tui/layout"
 	"github.com/sst/opencode/internal/tui/layout"
 	"github.com/sst/opencode/internal/tui/styles"
 	"github.com/sst/opencode/internal/tui/styles"
 	"github.com/sst/opencode/internal/tui/theme"
 	"github.com/sst/opencode/internal/tui/theme"
 	"github.com/sst/opencode/internal/tui/util"
 	"github.com/sst/opencode/internal/tui/util"
-	"path/filepath"
 	"strings"
 	"strings"
 )
 )
 
 
@@ -27,15 +24,15 @@ const (
 
 
 // PermissionResponseMsg represents the user's response to a permission request
 // PermissionResponseMsg represents the user's response to a permission request
 type PermissionResponseMsg struct {
 type PermissionResponseMsg struct {
-	Permission permission.PermissionRequest
-	Action     PermissionAction
+	// Permission permission.PermissionRequest
+	Action PermissionAction
 }
 }
 
 
 // PermissionDialogCmp interface for permission dialog component
 // PermissionDialogCmp interface for permission dialog component
 type PermissionDialogCmp interface {
 type PermissionDialogCmp interface {
 	tea.Model
 	tea.Model
 	layout.Bindings
 	layout.Bindings
-	SetPermissions(permission permission.PermissionRequest) tea.Cmd
+	// SetPermissions(permission permission.PermissionRequest) tea.Cmd
 }
 }
 
 
 type permissionsMapping struct {
 type permissionsMapping struct {
@@ -81,9 +78,9 @@ var permissionsKeys = permissionsMapping{
 
 
 // permissionDialogCmp is the implementation of PermissionDialog
 // permissionDialogCmp is the implementation of PermissionDialog
 type permissionDialogCmp struct {
 type permissionDialogCmp struct {
-	width           int
-	height          int
-	permission      permission.PermissionRequest
+	width  int
+	height int
+	// permission      permission.PermissionRequest
 	windowSize      tea.WindowSizeMsg
 	windowSize      tea.WindowSizeMsg
 	contentViewPort viewport.Model
 	contentViewPort viewport.Model
 	selectedOption  int // 0: Allow, 1: Allow for session, 2: Deny
 	selectedOption  int // 0: Allow, 1: Allow for session, 2: Deny
@@ -106,27 +103,27 @@ func (p *permissionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 		cmds = append(cmds, cmd)
 		cmds = append(cmds, cmd)
 		p.markdownCache = make(map[string]string)
 		p.markdownCache = make(map[string]string)
 		p.diffCache = make(map[string]string)
 		p.diffCache = make(map[string]string)
-	case tea.KeyMsg:
-		switch {
-		case key.Matches(msg, permissionsKeys.Right) || key.Matches(msg, permissionsKeys.Tab):
-			p.selectedOption = (p.selectedOption + 1) % 3
-			return p, nil
-		case key.Matches(msg, permissionsKeys.Left):
-			p.selectedOption = (p.selectedOption + 2) % 3
-		case key.Matches(msg, permissionsKeys.EnterSpace):
-			return p, p.selectCurrentOption()
-		case key.Matches(msg, permissionsKeys.Allow):
-			return p, util.CmdHandler(PermissionResponseMsg{Action: PermissionAllow, Permission: p.permission})
-		case key.Matches(msg, permissionsKeys.AllowSession):
-			return p, util.CmdHandler(PermissionResponseMsg{Action: PermissionAllowForSession, Permission: p.permission})
-		case key.Matches(msg, permissionsKeys.Deny):
-			return p, util.CmdHandler(PermissionResponseMsg{Action: PermissionDeny, Permission: p.permission})
-		default:
-			// Pass other keys to viewport
-			viewPort, cmd := p.contentViewPort.Update(msg)
-			p.contentViewPort = viewPort
-			cmds = append(cmds, cmd)
-		}
+		// case tea.KeyMsg:
+		// 	switch {
+		// 	case key.Matches(msg, permissionsKeys.Right) || key.Matches(msg, permissionsKeys.Tab):
+		// 		p.selectedOption = (p.selectedOption + 1) % 3
+		// 		return p, nil
+		// 	case key.Matches(msg, permissionsKeys.Left):
+		// 		p.selectedOption = (p.selectedOption + 2) % 3
+		// 	case key.Matches(msg, permissionsKeys.EnterSpace):
+		// 		return p, p.selectCurrentOption()
+		// 	case key.Matches(msg, permissionsKeys.Allow):
+		// 		return p, util.CmdHandler(PermissionResponseMsg{Action: PermissionAllow, Permission: p.permission})
+		// 	case key.Matches(msg, permissionsKeys.AllowSession):
+		// 		return p, util.CmdHandler(PermissionResponseMsg{Action: PermissionAllowForSession, Permission: p.permission})
+		// 	case key.Matches(msg, permissionsKeys.Deny):
+		// 		return p, util.CmdHandler(PermissionResponseMsg{Action: PermissionDeny, Permission: p.permission})
+		// 	default:
+		// 		// Pass other keys to viewport
+		// 		viewPort, cmd := p.contentViewPort.Update(msg)
+		// 		p.contentViewPort = viewPort
+		// 		cmds = append(cmds, cmd)
+		// 	}
 	}
 	}
 
 
 	return p, tea.Batch(cmds...)
 	return p, tea.Batch(cmds...)
@@ -144,7 +141,7 @@ func (p *permissionDialogCmp) selectCurrentOption() tea.Cmd {
 		action = PermissionDeny
 		action = PermissionDeny
 	}
 	}
 
 
-	return util.CmdHandler(PermissionResponseMsg{Action: action, Permission: p.permission})
+	return util.CmdHandler(PermissionResponseMsg{Action: action}) // , Permission: p.permission})
 }
 }
 
 
 func (p *permissionDialogCmp) renderButtons() string {
 func (p *permissionDialogCmp) renderButtons() string {
@@ -194,58 +191,59 @@ func (p *permissionDialogCmp) renderButtons() string {
 }
 }
 
 
 func (p *permissionDialogCmp) renderHeader() string {
 func (p *permissionDialogCmp) renderHeader() string {
-	t := theme.CurrentTheme()
-	baseStyle := styles.BaseStyle()
-
-	toolKey := baseStyle.Foreground(t.TextMuted()).Bold(true).Render("Tool")
-	toolValue := baseStyle.
-		Foreground(t.Text()).
-		Width(p.width - lipgloss.Width(toolKey)).
-		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) {
-		if cwd, err := filepath.Rel(config.WorkingDirectory(), relativePath); err == nil {
-			relativePath = cwd
-		}
-	}
-
-	pathValue := baseStyle.
-		Foreground(t.Text()).
-		Width(p.width - lipgloss.Width(pathKey)).
-		Render(fmt.Sprintf(": %s", relativePath))
-
-	headerParts := []string{
-		lipgloss.JoinHorizontal(
-			lipgloss.Left,
-			toolKey,
-			toolValue,
-		),
-		baseStyle.Render(strings.Repeat(" ", p.width)),
-		lipgloss.JoinHorizontal(
-			lipgloss.Left,
-			pathKey,
-			pathValue,
-		),
-		baseStyle.Render(strings.Repeat(" ", p.width)),
-	}
-
-	// Add tool-specific header information
-	switch p.permission.ToolName {
-	case "bash":
-		headerParts = append(headerParts, baseStyle.Foreground(t.TextMuted()).Width(p.width).Bold(true).Render("Command"))
-	case "edit":
-		headerParts = append(headerParts, baseStyle.Foreground(t.TextMuted()).Width(p.width).Bold(true).Render("Diff"))
-	case "write":
-		headerParts = append(headerParts, baseStyle.Foreground(t.TextMuted()).Width(p.width).Bold(true).Render("Diff"))
-	case "fetch":
-		headerParts = append(headerParts, baseStyle.Foreground(t.TextMuted()).Width(p.width).Bold(true).Render("URL"))
-	}
-
-	return lipgloss.NewStyle().Background(t.Background()).Render(lipgloss.JoinVertical(lipgloss.Left, headerParts...))
+	return "NOT IMPLEMENTED"
+	// t := theme.CurrentTheme()
+	// baseStyle := styles.BaseStyle()
+	//
+	// toolKey := baseStyle.Foreground(t.TextMuted()).Bold(true).Render("Tool")
+	// toolValue := baseStyle.
+	// 	Foreground(t.Text()).
+	// 	Width(p.width - lipgloss.Width(toolKey)).
+	// 	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) {
+	// 	if cwd, err := filepath.Rel(config.WorkingDirectory(), relativePath); err == nil {
+	// 		relativePath = cwd
+	// 	}
+	// }
+	//
+	// pathValue := baseStyle.
+	// 	Foreground(t.Text()).
+	// 	Width(p.width - lipgloss.Width(pathKey)).
+	// 	Render(fmt.Sprintf(": %s", relativePath))
+	//
+	// headerParts := []string{
+	// 	lipgloss.JoinHorizontal(
+	// 		lipgloss.Left,
+	// 		toolKey,
+	// 		toolValue,
+	// 	),
+	// 	baseStyle.Render(strings.Repeat(" ", p.width)),
+	// 	lipgloss.JoinHorizontal(
+	// 		lipgloss.Left,
+	// 		pathKey,
+	// 		pathValue,
+	// 	),
+	// 	baseStyle.Render(strings.Repeat(" ", p.width)),
+	// }
+	//
+	// // Add tool-specific header information
+	// switch p.permission.ToolName {
+	// case "bash":
+	// 	headerParts = append(headerParts, baseStyle.Foreground(t.TextMuted()).Width(p.width).Bold(true).Render("Command"))
+	// case "edit":
+	// 	headerParts = append(headerParts, baseStyle.Foreground(t.TextMuted()).Width(p.width).Bold(true).Render("Diff"))
+	// case "write":
+	// 	headerParts = append(headerParts, baseStyle.Foreground(t.TextMuted()).Width(p.width).Bold(true).Render("Diff"))
+	// case "fetch":
+	// 	headerParts = append(headerParts, baseStyle.Foreground(t.TextMuted()).Width(p.width).Bold(true).Render("URL"))
+	// }
+	//
+	// return lipgloss.NewStyle().Background(t.Background()).Render(lipgloss.JoinVertical(lipgloss.Left, headerParts...))
 }
 }
 
 
 func (p *permissionDialogCmp) renderBashContent() string {
 func (p *permissionDialogCmp) renderBashContent() string {
@@ -365,60 +363,61 @@ func (p *permissionDialogCmp) styleViewport() string {
 }
 }
 
 
 func (p *permissionDialogCmp) render() string {
 func (p *permissionDialogCmp) render() string {
-	t := theme.CurrentTheme()
-	baseStyle := styles.BaseStyle()
-
-	title := baseStyle.
-		Bold(true).
-		Width(p.width - 4).
-		Foreground(t.Primary()).
-		Render("Permission Required")
-	// Render header
-	headerContent := p.renderHeader()
-	// Render buttons
-	buttons := p.renderButtons()
-
-	// Calculate content height dynamically based on window size
-	p.contentViewPort.Height = p.height - lipgloss.Height(headerContent) - lipgloss.Height(buttons) - 2 - lipgloss.Height(title)
-	p.contentViewPort.Width = p.width - 4
-
-	// Render content based on tool type
-	var contentFinal string
-	switch p.permission.ToolName {
-	case "bash":
-		contentFinal = p.renderBashContent()
-	case "edit":
-		contentFinal = p.renderEditContent()
-	case "patch":
-		contentFinal = p.renderPatchContent()
-	case "write":
-		contentFinal = p.renderWriteContent()
-	case "fetch":
-		contentFinal = p.renderFetchContent()
-	default:
-		contentFinal = p.renderDefaultContent()
-	}
-
-	content := lipgloss.JoinVertical(
-		lipgloss.Top,
-		title,
-		baseStyle.Render(strings.Repeat(" ", lipgloss.Width(title))),
-		headerContent,
-		contentFinal,
-		buttons,
-		baseStyle.Render(strings.Repeat(" ", p.width-4)),
-	)
-
-	return baseStyle.
-		Padding(1, 0, 0, 1).
-		Border(lipgloss.RoundedBorder()).
-		BorderBackground(t.Background()).
-		BorderForeground(t.TextMuted()).
-		Width(p.width).
-		Height(p.height).
-		Render(
-			content,
-		)
+	return "NOT IMPLEMENTED"
+	// t := theme.CurrentTheme()
+	// baseStyle := styles.BaseStyle()
+	//
+	// title := baseStyle.
+	// 	Bold(true).
+	// 	Width(p.width - 4).
+	// 	Foreground(t.Primary()).
+	// 	Render("Permission Required")
+	// // Render header
+	// headerContent := p.renderHeader()
+	// // Render buttons
+	// buttons := p.renderButtons()
+	//
+	// // Calculate content height dynamically based on window size
+	// p.contentViewPort.Height = p.height - lipgloss.Height(headerContent) - lipgloss.Height(buttons) - 2 - lipgloss.Height(title)
+	// p.contentViewPort.Width = p.width - 4
+	//
+	// // Render content based on tool type
+	// var contentFinal string
+	// switch p.permission.ToolName {
+	// case "bash":
+	// 	contentFinal = p.renderBashContent()
+	// case "edit":
+	// 	contentFinal = p.renderEditContent()
+	// case "patch":
+	// 	contentFinal = p.renderPatchContent()
+	// case "write":
+	// 	contentFinal = p.renderWriteContent()
+	// case "fetch":
+	// 	contentFinal = p.renderFetchContent()
+	// default:
+	// 	contentFinal = p.renderDefaultContent()
+	// }
+	//
+	// content := lipgloss.JoinVertical(
+	// 	lipgloss.Top,
+	// 	title,
+	// 	baseStyle.Render(strings.Repeat(" ", lipgloss.Width(title))),
+	// 	headerContent,
+	// 	contentFinal,
+	// 	buttons,
+	// 	baseStyle.Render(strings.Repeat(" ", p.width-4)),
+	// )
+	//
+	// return baseStyle.
+	// 	Padding(1, 0, 0, 1).
+	// 	Border(lipgloss.RoundedBorder()).
+	// 	BorderBackground(t.Background()).
+	// 	BorderForeground(t.TextMuted()).
+	// 	Width(p.width).
+	// 	Height(p.height).
+	// 	Render(
+	// 		content,
+	// 	)
 }
 }
 
 
 func (p *permissionDialogCmp) View() string {
 func (p *permissionDialogCmp) View() string {
@@ -430,33 +429,33 @@ func (p *permissionDialogCmp) BindingKeys() []key.Binding {
 }
 }
 
 
 func (p *permissionDialogCmp) SetSize() tea.Cmd {
 func (p *permissionDialogCmp) SetSize() tea.Cmd {
-	if p.permission.ID == "" {
-		return nil
-	}
-	switch p.permission.ToolName {
-	case "bash":
-		p.width = int(float64(p.windowSize.Width) * 0.4)
-		p.height = int(float64(p.windowSize.Height) * 0.3)
-	case "edit":
-		p.width = int(float64(p.windowSize.Width) * 0.8)
-		p.height = int(float64(p.windowSize.Height) * 0.8)
-	case "write":
-		p.width = int(float64(p.windowSize.Width) * 0.8)
-		p.height = int(float64(p.windowSize.Height) * 0.8)
-	case "fetch":
-		p.width = int(float64(p.windowSize.Width) * 0.4)
-		p.height = int(float64(p.windowSize.Height) * 0.3)
-	default:
-		p.width = int(float64(p.windowSize.Width) * 0.7)
-		p.height = int(float64(p.windowSize.Height) * 0.5)
-	}
+	// if p.permission.ID == "" {
+	// 	return nil
+	// }
+	// switch p.permission.ToolName {
+	// case "bash":
+	// 	p.width = int(float64(p.windowSize.Width) * 0.4)
+	// 	p.height = int(float64(p.windowSize.Height) * 0.3)
+	// case "edit":
+	// 	p.width = int(float64(p.windowSize.Width) * 0.8)
+	// 	p.height = int(float64(p.windowSize.Height) * 0.8)
+	// case "write":
+	// 	p.width = int(float64(p.windowSize.Width) * 0.8)
+	// 	p.height = int(float64(p.windowSize.Height) * 0.8)
+	// case "fetch":
+	// 	p.width = int(float64(p.windowSize.Width) * 0.4)
+	// 	p.height = int(float64(p.windowSize.Height) * 0.3)
+	// default:
+	// 	p.width = int(float64(p.windowSize.Width) * 0.7)
+	// 	p.height = int(float64(p.windowSize.Height) * 0.5)
+	// }
 	return nil
 	return nil
 }
 }
 
 
-func (p *permissionDialogCmp) SetPermissions(permission permission.PermissionRequest) tea.Cmd {
-	p.permission = permission
-	return p.SetSize()
-}
+// func (p *permissionDialogCmp) SetPermissions(permission permission.PermissionRequest) tea.Cmd {
+// 	p.permission = permission
+// 	return p.SetSize()
+// }
 
 
 // Helper to get or set cached diff content
 // Helper to get or set cached diff content
 func (c *permissionDialogCmp) GetOrSetDiff(key string, generator func() (string, error)) string {
 func (c *permissionDialogCmp) GetOrSetDiff(key string, generator func() (string, error)) string {

+ 3 - 5
internal/tui/tui.go

@@ -13,8 +13,6 @@ import (
 	"github.com/sst/opencode/internal/config"
 	"github.com/sst/opencode/internal/config"
 	"github.com/sst/opencode/internal/tui/app"
 	"github.com/sst/opencode/internal/tui/app"
 
 
-	"github.com/sst/opencode/internal/permission"
-	"github.com/sst/opencode/internal/pubsub"
 	"github.com/sst/opencode/internal/status"
 	"github.com/sst/opencode/internal/status"
 	"github.com/sst/opencode/internal/tui/components/chat"
 	"github.com/sst/opencode/internal/tui/components/chat"
 	"github.com/sst/opencode/internal/tui/components/core"
 	"github.com/sst/opencode/internal/tui/components/core"
@@ -252,9 +250,9 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 
 
 		return a, tea.Batch(cmds...)
 		return a, tea.Batch(cmds...)
 
 
-	case pubsub.Event[permission.PermissionRequest]:
-		a.showPermissions = true
-		return a, a.permissions.SetPermissions(msg.Payload)
+	// case pubsub.Event[permission.PermissionRequest]:
+	// 	a.showPermissions = true
+	// 	return a, a.permissions.SetPermissions(msg.Payload)
 
 
 	case dialog.PermissionResponseMsg:
 	case dialog.PermissionResponseMsg:
 		// TODO: Permissions service not implemented in API yet
 		// TODO: Permissions service not implemented in API yet