Something went wrong. Try again.
small gleam coding and persistent agent daemon with a detachable cli and a canvas ui forked from okami.mom/albedo
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182// Bubble Tea comes from cli/third_party, patched so that a command run with// tea.Exec (the prompt editor, ssh sign-in) hands its result to the model// before any key read once the terminal is back (see// third_party/bubbletea.patch). Upstream sends that result from a goroutine,// so a key typed as the editor closes could reach the chat first and act on// the draft from before the edit: ctrl+g then reopened the editor on the old// text. E2E drives a real terminal but meets this race only now and then.package tui
import ( "io" "os" "testing" "time"
tea "charm.land/bubbletea/v2")
// typeAsItExits stands in for an editor the person leaves by typing on: its// last act writes a key to the terminal input.type typeAsItExits struct{ input *os.File }
func (c typeAsItExits) Run() error { _, err := c.input.WriteString("x") return err}func (typeAsItExits) SetStdin(io.Reader) {}func (typeAsItExits) SetStdout(io.Writer) {}func (typeAsItExits) SetStderr(io.Writer) {}
type execDoneMsg struct{}
type execOrderModel struct { input *os.File seen []string}
func (m execOrderModel) Init() tea.Cmd { return tea.Exec(typeAsItExits{m.input}, func(error) tea.Msg { return execDoneMsg{} })}
func (m execOrderModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case execDoneMsg: m.seen = append(m.seen, "exec") case tea.KeyPressMsg: m.seen = append(m.seen, msg.String()) } if len(m.seen) == 2 { return m, tea.Quit } return m, nil}
func (execOrderModel) View() tea.View { return tea.NewView("") }
func TestExecResultArrivesBeforeKeysTypedAsItEnds(t *testing.T) { read, write, err := os.Pipe() if err != nil { t.Fatal(err) } t.Cleanup(func() { read.Close(); write.Close() }) program := tea.NewProgram(execOrderModel{input: write}, tea.WithInput(read), tea.WithOutput(io.Discard)) done := make(chan tea.Model, 1) go func() { final, err := program.Run() if err != nil { t.Error(err) } done <- final }() select { case final := <-done: if seen := final.(execOrderModel).seen; len(seen) != 2 || seen[0] != "exec" || seen[1] != "x" { t.Fatalf("the model saw %v, want the exec result before the key", seen) } case <-time.After(10 * time.Second): program.Kill() t.Fatal("the program never saw both the exec result and the key") }}