• src/syncterm/scripts/connected.wren console.wren src/syncterm/wren/LIC

    From Deuc¨@VERT to Git commit to main/sbbs/master on Sunday, April 26, 2026 20:05:06
    https://gitlab.synchro.net/main/sbbs/-/commit/637e9e5bb5a98c2bae8d2122
    Added Files:
    src/syncterm/scripts/connected.wren console.wren src/syncterm/wren/LICENSE README.md src/syncterm/wren/include/wren.h wren.hpp src/syncterm/wren/optional/wren_opt_meta.c wren_opt_meta.h wren_opt_meta.wren wren_opt_meta.wren.inc wren_opt_random.c wren_opt_random.h wren_opt_random.wren wren_opt_random.wren.inc src/syncterm/wren/vm/wren_common.h wren_compiler.c wren_compiler.h wren_core.c wren_core.h wren_core.wren wren_core.wren.inc wren_debug.c wren_debug.h wren_math.h wren_opcodes.h wren_primitive.c wren_primitive.h wren_utils.c wren_utils.h wren_value.c wren_value.h wren_vm.c wren_vm.h src/syncterm/wren_bind.c wren_embed_gen.c wren_host.c wren_host.h wren_host_internal.h
    Modified Files:
    src/build/Common.gmake src/conio/cg_events.m ciolib.h retro.c sdl_con.c win32cio.c wl_events.c x_events.c src/syncterm/CMakeLists.txt DarwinWrappers.m GNUmakefile conn.c syncterm.c syncterm.h term.c
    Log Message:
    SyncTERM: Wren scripting host

    Embed the Wren VM as a per-connection scripting host. Each connection
    spins up its own VM at start, runs scripts, and tears it down on
    disconnect, so per-connection isolation falls out for free.

    Scripts come from two sources:

    * Embedded Ä shipped in the binary. scripts/*.wren is preprocessed
    at build time by wren_embed_gen (a small C99 codegen tool, host-CC
    compiled so cross-builds work) into a name+source table compiled
    alongside wren_host.c. Two ship today: console.wren (the REPL)
    and connected.wren (Alt+L send-login, extracted from term.c).
    * User overrides Ä files placed in the platform's user-data scripts
    directory (XDG \$XDG_DATA_HOME on Linux/BSD; Win32, macOS, and
    Haiku branches in syncterm.c) override the embedded script of the
    same module name, or add new ones.

    Six dispatch points are wired into doterm() / conn_send():
    keyboard, mouse, inbound bytes, outbound bytes, status text, and a
    periodic timer. Hooks consume or pass through; consumed events skip
    the rest of the pipeline. Owner thread is captured at init and
    non-owner dispatches short-circuit to pass-through (background SFTP
    and SSH writes call conn_send from worker threads).

    Foreign classes exposed to scripts:

    * Screen Ä global console ops (save/restore, attr, supports, font,
    palette, cursor, videoFlags, color, hyperlinkId, window scope).
    * Input Ä event-driven: next / next(ms) / poll return a KeyEvent or
    MouseEvent foreign object; nextEvent parks the calling Wren fiber
    and resumes it on the next event, giving scripts modal input
    without busy-spinning. While a fiber is parked, the remote-byte
    pump is gated off so server output can't paint over a dialog.
    Key.* constants (escape, f1-f12, shiftTab, mouse, ...) come from
    CIO_KEY_* in conio/ciolib.h; Esc-by-scancode is normalized to
    0x001B in the KeyEvent ctor so scripts only ever see one Esc.
    Input.unget(ev) routes by event type.
    * Clipboard Ä text getter/setter.
    * CTerm Ä read-only window into cterm state (cursor, origin,
    margins, color, fonts, scrollback geometry, mode flags), with
    ExtAttr / LastColumnFlag bitfield-snapshot classes and LogMode
    / StatusDisplay / Emulation / Codepage enum classes.
    * Conn Ä pending/queued/peek/recv/send/sendRaw. send() routes
    through conn_send so telnet IAC escaping and onOutput hooks
    fire; sendRaw is the bypass. peek/recv clamp to the actual
    inbuf size.
    * BBS Ä read-only struct bbslist getters (~30 fields) plus
    password / syspass and ConnType / FlowControl enum classes.
    * Cell / Cells / Font / Hyperlinks Ä vmem_gettext / puttext
    bindings. Cell wraps struct vmem_cell with separate
    palette/rgb getters and setters that preserve bits 24-30 of
    fg/bg; ch round-trips through CP437. Hyperlinks is Map-like
    with [id], containsKey, add, params. Font has named built-in
    indices plus runtime name(i) / available(i).
    * Cache Ä opaque Directory + File pair with strict 1..64-char
    [A-Za-z0-9._-] filename policy (rejects leading dot/dash,
    trailing dot, "..", Windows reserved device names). File
    covers open/close/read/write/delete/seek with deleted-handle
    poisoning.
    * Console Ä ring-buffered print/error log indexed by monotonic
    sequence so incremental rendering survives ring eviction.
    * Hook Ä registration API for the six dispatch events.

    REPL:

    * Ctrl+\` opens an immediate-mode REPL (console.wren). Compiles
    user input via wrenCompileSource directly so vars persist across
    submissions; runtime aborts caught with Fiber.try() and walked
    for a real stack trace. Compile-time errors that only mean
    "input wasn't an expression" are filtered through a side-log so
    expression-form printing works without dumping the noise.
    * Expression results print quoted with C-style escapes Ä "7" the
    string and 7 the number are visibly distinct.
    * Module-aware /in <module> moves the eval target. All embedded
    scripts (and any user override matching an embedded basename)
    share the "syncterm" module so console.wren can use Screen /
    Input / Cell / etc. directly and the REPL can inspect anything
    those scripts define. Pure user scripts keep file-per-module
    isolation.
    * /quit, /help, command history (Up/Down with prefix filter when
    text was typed first), Ctrl+W backward-kill-word, middle-click
    paste (LF-split, line-by-line submit), Alt+drag handoff to the
    existing mousedrag select-and-copy.

    Two pre-existing key-write bugs surfaced by adding the Ctrl+\`
    keytable entry (CIO_KEY_WREN_CONSOLE = 0x29E0) and are fixed here:
    both X11 and Wayland used "low byte non-zero -> 1 byte" as a
    stand-in for "ASCII", which fails for synthetic keys with both
    bytes set (low = 0xE0 marker, high = scancode). Aligned with
    cg_cio.m / win32gdi.c / sdl_con.c: write 2 bytes whenever the
    high byte is non-zero.

    GNUmakefile uses per-pattern -UPREFIX to silence Wren's PREFIX
    function-like macro colliding with SYNCTERM_PATH_PREFIX.

    The Wren VM (wren/) is vendored verbatim from the upstream Wren
    repository, MIT-licensed; LICENSE and README are checked in.

    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net