__                 _ _                _
  / _| ___   ___   __| | |__   __ _ _ __| | __
 | |_ / _ \ / _ \ / _` | '_ \ / _` | '__| |/ /
 |  _| (_) | (_) | (_| | |_) | (_| | |  |   <
 |_|  \___/ \___/ \__,_|_.__/ \__,_|_|  |_|\_\

A personal BBS  ·  Missoula, Montana  ·  formerly NaClCON BBS

Connect from your terminal: telnet naclconbbs.net 23  |  ssh naclconbbs.net -p 2222

  • src/syncterm/scripts/load/wrentest.wren src/syncterm/scripts/syncterm.

    From Deucе@VERT to Git commit to main/sbbs/master on Mon Apr 27 18:20:39 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/cf1981eeec2eb92ddfe3172e
    Modified Files:
    src/syncterm/scripts/load/wrentest.wren src/syncterm/scripts/syncterm.wren src/syncterm/wren_host.c wren_host_internal.h
    Log Message:
    SyncTERM: route Wren hook fires through Hook.dispatch_

    Every hook fire (onKey/onInput/onOutput/onMouse/onStatus/every) now
    goes through Hook.dispatch_(fn[, arg]) instead of fn.call() directly.
    The wrapper runs the handler in a child fiber via Fiber.try; if the
    handler yields directly (e.g. naively calls Input.nextEvent or a
    parking SFTP op at its top level), the wrapper detects f.isDone ==
    false, logs a clear error naming the right escape hatch, and returns
    null so the dispatcher's bool/string slot read falls through to passthrough/default. Errors are caught the same way and pushed
    through REPL.printTrace_ for visibility.

    Hook drops its (misleading) `foreign` modifier — it has no instance
    state and no allocator was ever registered. Plain `class` lets the
    new dispatch_ / finishDispatch_ methods sit alongside the foreign
    statics, matching the Color / ScreenSupports pattern.

    C dispatchers cache state.hook_class + dispatch0/dispatch1 method
    handles after the syncterm module loads, then push slot 0 = Hook,
    slot 1 = fn, slot 2+ = arg(s). build_match_list now takes a
    list_slot parameter so the regex match list can land at slot 2.

    Six tests in wrentest.wren cover: passthrough (1-arg, 0-arg, bool
    true/false), direct-yield rejection (1-arg, 0-arg), child-fiber
    yield permitted (the supported `Fiber.new { ... }.call()` pattern
    for parking work from inside a hook), and Fiber.abort caught.

    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

    ---
    ■ Synchronet ■ Vertrauen ■ Home of Synchronet ■ [vert/cvs/bbs].synchro.net