Skip to content

The /terminal docs page's TypeScript column is wrong: the pty key it shows binds nothing and its ptyWrite call does not transpile #252

Description

@sonhyrd

Summary

The /terminal docs page's TypeScript column shows a pty key that names nothing the
bridge spawns into, and an effect call the emitter refuses. Following it produces a
blank terminal with no error anywhere. The Zig column on the same page is correct.

Checked against the live page and v0.7.1 (19519dd5), 2026-08-01.

What the page shows

const shellKey = 1;
...
case "type":     return [model, Cmd.ptyWrite(shellKey, msg.bytes)];
case "viewport": return [model, Cmd.ptyResize(shellKey, msg.cols, msg.rows)];

and, in prose: "The pty key is ordinary model data — pick it like an effect key."

Why it does not work

  1. The key is not the app's to pick. For a TS core, Cmd.ptySpawn names a string
    session key; ts_core_host.zig maps it to the first free slot in its own table and
    spawns the engine session at pty_key_base + index
    (pub const pty_key_base: u64 = 0x5453_5054_0000_0000). <terminal pty={n}> must
    name that engine key. Binding 1 mounts nothing — no diagnostic, no log, an empty
    grid. (Background in Feature gap: a transpiled TS core cannot bind <terminal pty> — TS pty commands and the terminal element fail to meet at the binding #229.)
  2. A computed key is not expressible. Cmd.ptyWrite/ptyKill take the key as a
    string literal (NS1027), so Cmd.ptyWrite(shellKey, …) — a variable — does not
    transpile at all. The page's own snippet fails the checker.

Why it survived

None of the three core.ts examples the SDK ships (ai-chat-ts, soundboard-ts,
system-monitor-ts) mounts a <terminal>, so the TS-core + terminal combination has no
example holding the page honest.

What a correct column needs to say

  • the spawn key is a string literal, and every later op naming it is a literal too;
  • the value <terminal pty> binds is the engine key, pty_key_base + slot, not the
    string and not an app-chosen number;
  • the core is never told its slot, so it either mirrors the bridge's first-free-slot
    allocation or reads the bound key back from TerminalState.pty (feat(terminal): carry the bound pty key on canvas.TerminalState #221).

Related: #229 (the binding gap this page post-dates), #224.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions