• src/sbbs3/chat.cpp

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Fri May 29 02:00:51 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/2a0ee8dd1af8b0aad31440fb
    Modified Files:
    src/sbbs3/chat.cpp
    Log Message:
    chat.cpp: hoist declarations to satisfy GCC's "goto crosses init" rule

    Build broke on GCC (linux-x64 CI) in chat_llm_session() and chat_llm_multinode_turn() -- introduced in 683147f9c -- because the
    gotos to js_done / mt_done / cleanup labels skipped past
    initializations of local variables that were still in scope at the
    label. MSVC accepts this with at most a warning; GCC errors.

    Fixes:
    - chat_llm_session(): hoisted `bool supports_utf8` above any
    `goto cleanup`. Hoisted `double speed_factor` / `bool sim_typos`
    to the top of the JS_BEGINREQUEST block, above any `goto js_done`
    from within (they were below the gotos but in the same scope as
    the label).
    - chat_llm_multinode_turn(): hoisted `bool supports_utf8` above any
    `goto mt_done`. Wrapped the `JSString* input_str` / `jsval
    chat_args[]` declarations in an inner brace block so they fall
    out of scope before `mt_done:` instead of straddling it.

    Verified locally by single-file MSVC build of chat.cpp (0 errors,
    0 warnings). Structural fix targets exactly the cross-init errors
    GCC reported.

    CI failure: https://gitlab.synchro.net/main/sbbs/-/jobs/1509516

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Sun Jun 21 00:59:50 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/525bfd166fe44c4405da4ecb
    Modified Files:
    src/sbbs3/chat.cpp
    Log Message:
    chat: emit UTF-8 guru replies correctly to UTF-8 terminals (fix mojibake)

    Guru replies come off the LLM as UTF-8, but they were pushed through CP437-assuming output primitives that re-encode each byte to the
    terminal charset. On a UTF-8 terminal this double-encoded every
    multibyte character into mojibake (e.g. a curly apostrophe shown as
    three glyphs), and any node-spy (sbbsctrl, mqtt_spy.js) mirroring the
    node's byte stream saw the same corruption.

    Fix both output paths:

    - Multinode (chat_llm_multinode_turn): stop pre-converting the reply to
    CP437 based on the reader's terminal and emit with bprintf(P_AUTO_UTF8,
    ...). The reply stays UTF-8; bputs() adapts per terminal -- raw UTF-8
    to a UTF-8 term, print_utf8_as_cp437() to a CP437 term.

    - 1-on-1 streamed and non-streamed (simulate_type, the shared chokepoint
    reached via js_simulate_type and chat_llm_session): when the terminal
    is UTF-8, emit each multibyte codepoint atomically via bputs(seq,
    P_UTF8) instead of byte-by-byte outchar(). Typo simulation correctly
    applies to ASCII only. Robust to a codepoint split across SSE tokens
    (bytes still go out raw and in order). The speed_factor<=0 fast path
    uses P_AUTO_UTF8.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

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