wip: refactoring tui

This commit is contained in:
adamdottv
2025-05-28 15:36:31 -05:00
parent 8863a499a9
commit 9d7c5efb9b
21 changed files with 136 additions and 1346 deletions

View File

@@ -1,32 +0,0 @@
package main
import (
"context"
"os"
"os/signal"
"github.com/sst/opencode/pkg/app"
"github.com/sst/opencode/pkg/server"
"golang.org/x/sync/errgroup"
)
func main() {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
cwd, _ := os.Getwd()
app, err := app.New(ctx, cwd)
if err != nil {
panic(err)
}
server, err := server.New(app)
var wg errgroup.Group
wg.Go(func() error {
defer stop()
return server.Start(ctx)
})
<-ctx.Done()
wg.Wait()
}

View File

@@ -13,35 +13,15 @@ import (
tea "github.com/charmbracelet/bubbletea"
zone "github.com/lrstanley/bubblezone"
"github.com/spf13/cobra"
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/config"
"github.com/sst/opencode/internal/logging"
"github.com/sst/opencode/internal/lsp/discovery"
"github.com/sst/opencode/internal/pubsub"
"github.com/sst/opencode/internal/tui"
"github.com/sst/opencode/internal/tui/app"
"github.com/sst/opencode/internal/version"
)
type SessionIDHandler struct {
slog.Handler
app *app.App
}
func (h *SessionIDHandler) Handle(ctx context.Context, r slog.Record) error {
if h.app != nil {
sessionID := h.app.CurrentSession.ID
if sessionID != "" {
r.AddAttrs(slog.String("session_id", sessionID))
}
}
return h.Handler.Handle(ctx, r)
}
func (h *SessionIDHandler) WithApp(app *app.App) *SessionIDHandler {
h.app = app
return h
}
var rootCmd = &cobra.Command{
Use: "OpenCode",
Short: "A terminal AI assistant for software development",
@@ -244,10 +224,6 @@ func setupSubscriptions(app *app.App, parentCtx context.Context) (chan tea.Msg,
wg := sync.WaitGroup{}
ctx, cancel := context.WithCancel(parentCtx) // Inherit from parent context
// setupSubscriber(ctx, &wg, "logging", app.Logs.Subscribe, ch)
// setupSubscriber(ctx, &wg, "sessions", app.Sessions.Subscribe, ch)
// setupSubscriber(ctx, &wg, "messages", app.Messages.Subscribe, ch)
// setupSubscriber(ctx, &wg, "permissions", app.Permissions.Subscribe, ch)
setupSubscriber(ctx, &wg, "status", app.Status.Subscribe, ch)
cleanupFunc := func() {

View File

@@ -1,143 +0,0 @@
package cmd
import (
"bytes"
"io"
"os"
"testing"
)
func TestCheckStdinPipe(t *testing.T) {
// Save original stdin
origStdin := os.Stdin
// Restore original stdin when test completes
defer func() {
os.Stdin = origStdin
}()
// Test case 1: Data is piped in
t.Run("WithPipedData", func(t *testing.T) {
// Create a pipe
r, w, err := os.Pipe()
if err != nil {
t.Fatalf("Failed to create pipe: %v", err)
}
// Replace stdin with our pipe
os.Stdin = r
// Write test data to the pipe
testData := "test piped input"
go func() {
defer w.Close()
w.Write([]byte(testData))
}()
// Call the function
data, hasPiped := checkStdinPipe()
// Check results
if !hasPiped {
t.Error("Expected hasPiped to be true, got false")
}
if data != testData {
t.Errorf("Expected data to be %q, got %q", testData, data)
}
})
// Test case 2: No data is piped in (simulated terminal)
t.Run("WithoutPipedData", func(t *testing.T) {
// Create a temporary file to simulate a terminal
tmpFile, err := os.CreateTemp("", "terminal-sim")
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
// Open the file for reading
f, err := os.Open(tmpFile.Name())
if err != nil {
t.Fatalf("Failed to open temp file: %v", err)
}
defer f.Close()
// Replace stdin with our file
os.Stdin = f
// Call the function
data, hasPiped := checkStdinPipe()
// Check results
if hasPiped {
t.Error("Expected hasPiped to be false, got true")
}
if data != "" {
t.Errorf("Expected data to be empty, got %q", data)
}
})
}
// This is a mock implementation for testing since we can't easily mock os.Stdin.Stat()
// in a way that would return the correct Mode() for our test cases
func mockCheckStdinPipe(reader io.Reader, isPipe bool) (string, bool) {
if !isPipe {
return "", false
}
data, err := io.ReadAll(reader)
if err != nil {
return "", false
}
if len(data) > 0 {
return string(data), true
}
return "", false
}
func TestMockCheckStdinPipe(t *testing.T) {
// Test with data
t.Run("WithData", func(t *testing.T) {
testData := "test data"
reader := bytes.NewBufferString(testData)
data, hasPiped := mockCheckStdinPipe(reader, true)
if !hasPiped {
t.Error("Expected hasPiped to be true, got false")
}
if data != testData {
t.Errorf("Expected data to be %q, got %q", testData, data)
}
})
// Test without data
t.Run("WithoutData", func(t *testing.T) {
reader := bytes.NewBufferString("")
data, hasPiped := mockCheckStdinPipe(reader, true)
if hasPiped {
t.Error("Expected hasPiped to be false, got true")
}
if data != "" {
t.Errorf("Expected data to be empty, got %q", data)
}
})
// Test not a pipe
t.Run("NotAPipe", func(t *testing.T) {
reader := bytes.NewBufferString("data that should be ignored")
data, hasPiped := mockCheckStdinPipe(reader, false)
if hasPiped {
t.Error("Expected hasPiped to be false, got true")
}
if data != "" {
t.Errorf("Expected data to be empty, got %q", data)
}
})
}