Fix silent display failure on Windows by replacing /dev/tty with stdout fallback #2

Merged
Copilot merged 2 commits from copilot/fix-example-windows-display into main 2026-03-01 11:59:04 -08:00
Copilot commented 2026-03-01 11:56:37 -08:00 (Migrated from github.com)

with_terminal unconditionally opened /dev/tty which doesn't exist on Windows, causing apps to run (consuming CPU) but produce no output.

Changes

  • src/terminal.jlwith_terminal
    • Replace hardcoded /dev/tty open with a conditional: use provided tty_out if given, fall back to stdout on Windows, otherwise open /dev/tty (unchanged Unix behavior)
    • Guard the finally close to skip stdout (tty_io !== stdout && ...) to avoid closing the global stream on Windows
Original prompt

This section details on the original issue you should resolve

<issue_title>Example doesn't work on windows</issue_title>
<issue_description>I'm trying the example in the Quick Start section in windows terminal, it doesn't crash but it shows nothing. It's using CPU so I think it's doing something in the background but just doesn't display.

Image

Windows Terminal
Version : 1.23.20211.0

Julia 1.12.5 </issue_description>

<agent_instructions>Merge the windows-support branch with the fix</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@kahliburke Hi, thanks for trying the framework. I don't have a Windows system so it makes testing this more difficult.

You didn't show the full source that would be needed to get the app running, here is the minimal app source that works for me.

using Tachikoma
@tachikoma_app

@kwdef mutable struct Life <: Model
    quit::Bool = false
    grid::Matrix{Bool} = rand(24, 80) .< 0.25
end

should_quit(m::Life) = m.quit
function update!(m::Life, e::KeyEvent)
    e.key == :escape && (m.quit = true)
end

function view(m::Life, f::Frame)
    h, w = size(m.grid)
    g = m.grid
    nc = [sum(g[mod1(i+di,h), mod1(j+dj,w)]
          for di in -1:1, dj in -1:1) - g[i,j]
          for i in 1:h, j in 1:w]
    g .= (nc .== 3) .| (g .& (nc .== 2))
    a, buf = f.area, f.buffer
    cs = [:primary, :accent, :success,
          :warning, :error]
    for i in 1:min(h, a.height),
        j in 1:min(w, a.width)
        g[i,j] || continue
        set_char!(buf, a.x+j-1, a.y+i-1,
            '█', tstyle(cs[clamp(nc[i,j],1,5)]))
    end
end
app(Life())

Is that what you are running?</comment_new>


Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

`with_terminal` unconditionally opened `/dev/tty` which doesn't exist on Windows, causing apps to run (consuming CPU) but produce no output. ## Changes - **`src/terminal.jl` — `with_terminal`** - Replace hardcoded `/dev/tty` open with a conditional: use provided `tty_out` if given, fall back to `stdout` on Windows, otherwise open `/dev/tty` (unchanged Unix behavior) - Guard the `finally` close to skip `stdout` (`tty_io !== stdout && ...`) to avoid closing the global stream on Windows <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>Example doesn't work on windows</issue_title> > <issue_description>I'm trying the example in the Quick Start section in windows terminal, it doesn't crash but it shows nothing. It's using CPU so I think it's doing something in the background but just doesn't display. > > <img width="642" height="447" alt="Image" src="https://github.com/user-attachments/assets/013b4c0f-7476-49c0-ba98-17d40523e3fb" /> > > Windows Terminal > Version : 1.23.20211.0 > > Julia 1.12.5 </issue_description> > > <agent_instructions>Merge the windows-support branch with the fix</agent_instructions> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > <comment_new><author>@kahliburke</author><body> > Hi, thanks for trying the framework. I don't have a Windows system so it makes testing this more difficult. > > You didn't show the full source that would be needed to get the app running, here is the minimal app source that works for me. > > ``` > using Tachikoma > @tachikoma_app > > @kwdef mutable struct Life <: Model > quit::Bool = false > grid::Matrix{Bool} = rand(24, 80) .< 0.25 > end > > should_quit(m::Life) = m.quit > function update!(m::Life, e::KeyEvent) > e.key == :escape && (m.quit = true) > end > > function view(m::Life, f::Frame) > h, w = size(m.grid) > g = m.grid > nc = [sum(g[mod1(i+di,h), mod1(j+dj,w)] > for di in -1:1, dj in -1:1) - g[i,j] > for i in 1:h, j in 1:w] > g .= (nc .== 3) .| (g .& (nc .== 2)) > a, buf = f.area, f.buffer > cs = [:primary, :accent, :success, > :warning, :error] > for i in 1:min(h, a.height), > j in 1:min(w, a.width) > g[i,j] || continue > set_char!(buf, a.x+j-1, a.y+i-1, > '█', tstyle(cs[clamp(nc[i,j],1,5)])) > end > end > app(Life()) > ``` > > Is that what you are running?</body></comment_new> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes kahliburke/Tachikoma.jl#1 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/kahliburke/Tachikoma.jl/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.
Sign in to join this conversation.
No description provided.