• src/syncterm/scripts/auto

    From Deuc¿@VERT to Git commit to main/sbbs/m on Tuesday, April 28, 2026 04:20:00
    https://gitlab.synchro.net/main/sbbs/-/commit/54756ede4f29cb760ab5cbfb
    Added Files:
    src/syncterm/scripts/auto/connected/connected.wren console.wren runtests.wren src/syncterm/scripts/wrentest.wren
    Modified Files:
    src/syncterm/CMakeLists.txt GNUmakefile Wren.adoc wren_embed_gen.c wren_host.c wren_host_internal.h
    Log Message:
    SyncTERM: split Wren scripts into lazy lib vs auto-loaded entry trees

    Files at scripts/*.wren are pure library modules (loaded only when
    imported). Files at scripts/auto/<event>/*.wren auto-run when the
    framework fires <event> Ä currently only "connected" exists, but the
    layout reserves room for "startup", "ssh", "ui", etc.

    wren_embed_gen now infers the event from the path and emits it as a
    new field on struct embedded_script; entries with event=NULL are
    libraries. The host filters the auto-load loop by event match.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Wednesday, April 29, 2026 14:39:00
    https://gitlab.synchro.net/main/sbbs/-/commit/1e24b4a19f625ec9b73a1357
    Modified Files:
    src/syncterm/scripts/auto/connected/console.wren src/syncterm/wren_bind_screen.c
    Log Message:
    SyncTERM: console UTF-8 Ä fix byte/codepoint mismatches in print path

    Two paired bugs that together caused test labels with multi-byte
    UTF-8 (em-dashes, arrows, box-drawing) to render as garbled +
    truncated text in the Wren console viewport.

    wren_bind_screen.c Ä fnScreenWindow_print used to putch each input
    byte individually, so a 3-byte em-dash advanced the cursor by 3
    columns and rendered as 3 garbage CP437 cells (â € ”). Now decodes
    codepoint by codepoint and maps each via cpchar_from_unicode_cpoint(CIOLIB_CP437, cp, '?') before a single
    putch Ä same path Cell.ch= already takes Ä so cursor advance ==
    rendered cell count and unmappable codepoints fall back to '?'.
    Invalid UTF-8 still passes through as a single raw byte for binary
    output.

    scripts/auto/connected/console.wren Ä String.count is codepoint
    count (Sequence iteration yields one codepoint per step), but
    String[i] / String[a...b] are byte indexed via
    wrenStringCodePointAt + calculateRange against string->length.
    Mixing the two in put_() truncated multi-byte log output by
    (bytes - codepoints) at the tail. Same trap was present across
    the input-line editor (BS, Del, arrows, Home/End, Ctrl+W, history
    recall) where cursor is byte-shaped but every end-of-input boundary
    was input.count. Switch to s.bytes.count everywhere a byte count
    was meant. No change for ASCII-only paths.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Friday, May 01, 2026 09:47:00
    https://gitlab.synchro.net/main/sbbs/-/commit/79b77e1e01d974b65af40834
    Added Files:
    src/syncterm/scripts/auto/connected/sftp_browser.wren
    Modified Files:
    src/syncterm/scripts/syncterm.wren ui_app.wren ui_popup.wren src/syncterm/wren_bind.c wren_bind_sftp.c wren_bind_sftp.h
    Log Message:
    SyncTERM: Wren SFTP browser

    New scripts/auto/connected/sftp_browser.wren replaces the C-side
    sftp_browser.c for read-only navigation of an SFTP session. Bound
    to Alt-S; spawns a child fiber whose App owns the screen (CTerm
    suspended while modal).

    Display:
    - Each row shows size, mtime, an optional `+` marker (when the
    server's fattr advertises a non-empty descs@syncterm.net
    extension), and a label. Directories use lname when the
    server provides one; files keep their bare filename and put
    lname into a bottom description bar inside the pane.
    - F2 fetches the long description via the descs request and
    displays it preformatted (block-centred, no per-line centring).
    - Esc / [X] dismiss; F1 / [?] show help; Enter descends into
    directories; .. ascends. Files don't transfer yet Ä that
    lands with the Wren queue replacement.

    C-side wiring (wren_bind_sftp.[ch], wren_bind.c):
    - struct wren_sftp_entry gains has_long_desc; build_sftp_entry
    populates it from sftp_fattr_get_ext_by_type(de->attrs,
    SFTP_EXT_NAME_DESCS).
    - SFTPEntry foreign class gains hasLongDesc accessor.

    ui_app.wren:
    - dispatchMouse_ now hands an unclaimed button-1 drag-start back
    to the C-side selector (Input.unget(me) + Input.mousedrag()),
    so the standard SyncTERM rectangle / line-copy UI works while
    a Wren App is up.

    ui_popup.wren:
    - New splitHardLines_ helper splits on CR/LF/CRLF without
    word-wrapping. longestHardLine_ now counts codepoints rather
    than bytes so multi-byte UTF-8 (e.g. box-drawing) doesn't
    inflate the popup width measurement.
    - Popup gains a `preformatted` mode and Alert.showPreformatted:
    splits only on hard breaks (no word-wrap, no mid-codepoint
    splits) and left-aligns all lines at one block-column so the
    block is centred while each line keeps its relative shape.
    centeredBounds_ takes a preformatted flag for consistent row
    counting between sizing and painting.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, May 03, 2026 20:25:00
    https://gitlab.synchro.net/main/sbbs/-/commit/3c07fd6b3e95371b562d66c6
    Added Files:
    src/syncterm/scripts/auto/connected/status_default.wren
    Modified Files:
    src/syncterm/Wren.adoc src/syncterm/scripts/syncterm.wren src/syncterm/term.c wren_bind.c wren_bind_conn.c wren_bind_conn.h wren_bind_hook.c wren_bind_hook.h wren_bind_screen.c wren_bind_screen.h wren_host.c wren_host.h wren_host_internal.h
    Log Message:
    SyncTERM: reimplement status bar in Wren

    The C update_status() now hands a pre-filled width¨1 Surface to a Wren
    callable installed via Status.callable=(fn). The default
    implementation lives in scripts/auto/connected/status_default.wren and
    can be replaced by dropping a same-named file into the user's
    auto-load dir or by reassigning Status.callable from any later script.

    Improvements over the old C bar:
    * Speed gets its own slot to the right of the connection type, so
    long serial speeds (921600+) no longer truncate the BBS-name field.
    * Indicators (mouse 'M', SFTP arrows) right-pin to the row's right
    edge instead of fixed columns 27..30, so they stay readable at
    any width.

    Hook.onStatus is removed; new accessors expose the data the default
    script needs (BBS.elapsedSeconds, BBS.connTypeName, CTerm.atasciiInverse, CTerm.ooiiMode, CTerm.mouseMode, CTerm.mouseDisabled, Host.safeMode).
    The Surface is recycled across renders, reallocated only on width
    change, so per-frame allocation churn stays out of the hot path.

    Host.uploadArrow/downloadArrow move to pure Wren statics on the Host
    class -- the C-side xfer_*_arrow flags and wren_*_arrow_lit helpers
    are gone. Setters auto-call CTerm.refreshStatus() so writers don't
    need to remember.

    Wren.adoc updated to document the Status class, the new accessors,
    the Host.uploadArrow/downloadArrow getter+setter shape, and the
    removal of Hook.onStatus.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, May 03, 2026 21:13:00
    https://gitlab.synchro.net/main/sbbs/-/commit/0c972d847cf735d2e8e9a3ef
    Added Files:
    src/syncterm/scripts/auto/connected/keys_default.wren
    Modified Files:
    src/syncterm/Wren.adoc src/syncterm/scripts/auto/connected/status_default.wren src/syncterm/scripts/syncterm.wren src/syncterm/term.c term.h wren_bind.c wren_bind_conn.c wren_bind_conn.h wren_host.c wren_host.h wren_host_internal.h
    Log Message:
    SyncTERM: move Alt-O / Alt-Up / Alt-Down handlers to Wren

    The three remaining in-terminal Alt-shortcuts that lived as case
    blocks in term.c's input switch (Alt-O = toggle mouse-event
    reporting; Alt-Up / Alt-Down = walk the network throttle rate up /
    down the rates ladder) now live in scripts/auto/connected/
    keys_default.wren as Hook.onKey handlers, matching the existing
    Alt-L (login) pattern.

    New C primitives the script needs:
    * CTerm.mouseDisabled = b -- toggle the live mouse_state's
    MS_FLAGS_DISABLED bit.
    * Input.setupMouseEvents() -- wraps setup_mouse_events(&ms) +
    showmouse(), call after mutating mouse state.
    * CTerm.throttleSpeed (getter), CTerm.throttleSpeedUp() /
    throttleSpeedDown() (no-op on serial). Backed by doterm()'s
    local `speed` via wren_host_bind_speed(), mirroring the
    ooii_mode binding.

    Also adds Key.altUp (0x9800) and Key.altDown (0xA000), and adds
    the missing CTerm.atasciiInverse / ooiiMode / mouseMode /
    mouseDisabled foreign-method declarations to syncterm.wren that
    the previous status-bar commit had registered in BINDINGS but
    forgotten to declare on the class.

    status_default.wren now reads CTerm.throttleSpeed (the live rate
    the user can modulate) instead of BBS.bpsRate (the configured
    port speed). Falls back to BBS.bpsRate on serial connections,
    matching the historical C update_status() behaviour.

    Wren.adoc updated for all of the above.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, May 03, 2026 21:13:00
    https://gitlab.synchro.net/main/sbbs/-/commit/b6aa4e17a78368397616d347
    Modified Files:
    src/syncterm/scripts/auto/connected/keys_default.wren status_default.wren src/syncterm/scripts/syncterm.wren src/syncterm/wren_bind.c wren_bind_conn.c wren_bind_conn.h wren_host.c
    Log Message:
    SyncTERM: fix and polish the Wren-driven status bar

    A handful of bugs in the initial cut, plus a layout rework in
    response to first impressions.

    Bugs:
    * wren_status_render gated surface-class capture on
    `wrenGetSlotType != WREN_TYPE_UNKNOWN`, which is exactly the case
    the API returns for class objects -- so the handle was never
    cached and every render fell through to the C blank fallback,
    leaving an empty blue row.
    * BBS.connTypeName / BBS.elapsedSeconds were registered in
    BINDINGS but had no `foreign static` declaration on the BBS
    class, so the script crashed at first read.
    * keys_default.wren had `;` separators inside its single-line
    Hook.onKey block bodies (Wren rejects ';' as a token), and used
    `return` inside single-line `{ ... }` blocks (which are
    expression-mode and reject statements).
    * status_default.wren had the same `;` issue inside writeSep_.
    * throttle_step_'s ALT-Up path guarded `if (next != 0)`, dropping
    the rates[] sentinel that doubles as "unthrottled". ALT-Up from
    115200 now correctly cycles back to 0 (matching ALT-Down from 0
    wrapping to 115200).

    Layout rework:
    * Right-anchored: name field expands so "ALT-Z menu" ends one cell
    from the right edge, instead of trailing 4 cells of dead space.
    * "Connected: " label restored. Dropped only when keeping it
    would force the BBS name to truncate -- the label is decoration,
    the name is information.
    * Speed back inline with the name, matching the C original's flag
    order (SAFE, Logging, (speed), DrWy, OOTerm*, INV). The
    per-slot "115200 bps" rendering was an unnecessary divergence.
    * Indicator block (log , SFTP , SFTP , mouse M) painted at the
    right end of the name area instead of fixed columns 27..30, so
    it doesn't waste 3-4 cells of name space when the name area is
    wider than the original avail=30 cap. Mouse 'M' sits one cell
    in from the name-area edge so a padding space buffers it from
    the " ³ Conn " separator.
    * REPL log indicator wired up via new Host.logUnread /
    Host.logUnreadError bindings (the original C wires were
    unbound; the indicator was permanently blank).

    The Status callable now also reads the live CTerm.throttleSpeed
    that Alt-Up/Down adjusts, instead of the static BBS.bpsRate.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Monday, May 04, 2026 09:29:00
    https://gitlab.synchro.net/main/sbbs/-/commit/811f5588743a4178e8705abc
    Added Files:
    src/syncterm/scripts/auto/connected/capture_menu.wren
    Modified Files:
    src/syncterm/Wren.adoc src/syncterm/scripts/auto/connected/keys_default.wren status_default.wren src/syncterm/scripts/syncterm.wren ui_list.wren src/syncterm/term.c term.h wren_bind.c wren_bind_conn.c wren_bind_conn.h wren_bind_fs.c wren_bind_fs.h
    Log Message:
    SyncTERM: move capture / scrollback / paste keys to Wren + write-consent File

    Continues hollowing out doterm()'s key switch into Wren-driven Hook.onKey defaults. Adds the bindings the Wren handlers need, plus a write-consent flavour on the File class so we can ask the user to pick a save path
    without handing scripts open-ended write access to the local filesystem.

    Capture (streaming-log control):
    New foreign class Ä Capture.active / paused / start(file, raw) /
    stop / pause / resume. Replaces CTerm.logMode and CTerm.logPaused
    (those getters are gone; Capture.active and Capture.paused are
    bools and live where the verbs live). start(file, raw) consumes
    a write-consent File and transfers the FILE pointer into cterm's
    logfile.

    CTerm.saveScreenshot(file, withSauce):
    One-shot binary screen save (IBM-CGA / BinaryText), optionally with
    a SAUCE block populated from the active BBS. Snapshot is the cterm
    area only Ä status bar excluded. Consumes the File's write consent.

    Host.pickSavePath(initialDir, mask):
    uifc filepick wrapped with ALLOWENTRY + OVERPROMPT. Returns a
    write-consent File (or null on cancel). Open mode is determined
    by the picker outcome: WFC_CREATE ("wbx") for new paths,
    WFC_OVERWRITE ("wb") when the user confirmed overwrite.

    Write consent on File:
    New consent class on the File foreign Ä File.open() honors the
    authorized mode and consumes the consent on first close. Re-using
    the handle aborts the fiber. Token is intentionally null on
    write-consent Files (the read-side .token / Host.openLocalFile
    flow for upload resume is unaffected).

    Race-safety: WFC_CREATE uses fopen "wbx" (C11 exclusive create) so
    an attacker can't substitute a different file between the picker's
    existence check and our open().

    Capture menu (scripts/auto/connected/capture_menu.wren):
    Wren App that drives the Alt-C user flow. Three states based on
    Capture.active/paused: not-capturing  type list (ASCII / Raw /
    Binary [+SAUCE])  save picker  start; paused  Unpause/Close;
    active  Pause/Close. Replaces the C-side capture_control() uifc
    dialog for the Alt-C path (the Alt-Z menu still calls the C version
    until we migrate that too).

    Trivial-key migrations (Hook.onKey in keys_default.wren):
    - Shift-Insert  Conn.paste() (wraps do_paste Ä codepage- and
    bracketed-paste-aware).
    - Alt-B  Conn.scrollback() (wraps viewscroll() with
    mouse-event disable / restore).
    - Alt-C  CaptureMenu.run() (described above).
    Corresponding cases removed from doterm()'s switch.

    ListView fix (drive-by):
    ui_list.wren onPaint_ row-highlight fill now spans the full widget
    width (excluding the scrollbar column when present), so the
    selected-row lightbar reads as a single edge-to-edge bar instead
    of leaving the padding cells in default style. Fixes the
    ListView.draw rows-rendered test that regressed when the inset
    padding was added.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Monday, May 04, 2026 13:42:00
    https://gitlab.synchro.net/main/sbbs/-/commit/7afd5a9324163e299419def8
    Added Files:
    src/syncterm/scripts/auto/connected/disconnect_flow.wren music_menu.wren online_menu.wren
    Modified Files:
    src/syncterm/Wren.adoc menu.c menu.h src/syncterm/scripts/auto/connected/keys_default.wren src/syncterm/scripts/syncterm.wren src/syncterm/term.c term.h wren_bind.c wren_bind_conn.c wren_bind_conn.h
    Log Message:
    SyncTERM: move Alt-Z / Ctrl-S online menu to Wren

    The Alt-Z / Ctrl-S syncmenu dispatch in term.c, and the syncmenu()
    function it called, are gone. In their place: online_menu.wren
    registers Hook.onKey(Key.altZ) (always) and Hook.onKey(Key.ctrlS)
    (text-mode only) and drives an App + Pane + ListView modal that
    dispatches the selection back into Wren primitives Ä Conn.scrollback, Conn.upload / download, CaptureMenu.run, MusicMenu.run,
    Host.fontControl, Host.editBBSList, WrenConsole.run, etc. The
    Output Rate and Log Level entries chain into a sub-list before
    closing. Disconnect / Exit selections call Conn.endSession directly
    (no Confirm popup Ä the menu pick is itself the confirmation; the
    hot-key paths still go through DisconnectFlow).

    Selected actions run AFTER the menu's Screen.modalRun returns and
    the screen snapshot has been restored, so viewscroll()'s bottom-row
    capture sees the live terminal contents instead of menu pixels.
    The two sub-flows wrap themselves in their own Screen.modalRun.

    DisconnectFlow lifted out of keys_default.wren into its own module
    so online_menu can reuse it. MusicMenu likewise extracted from the
    inline Alt-M handler.

    New foreigns:
    Conn.upload(), Conn.download()
    CTerm.doorwayMode=, CTerm.ooiiMode (get/set), CTerm.throttleSpeed=
    Host.outputRates / outputRateNames
    Host.logLevel (get/set) / logLevelNames
    Host.fontControl(), Host.editBBSList()
    Host.haveOOII, Host.maxOOIIMode

    Removed (now-dead with syncmenu gone):
    syncmenu() and enum SM_* in menu.c / menu.h
    music_control() and capture_control() in term.c (orphans from the
    Alt-M / Alt-C migrations whose only caller was syncmenu)

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Tuesday, May 05, 2026 05:32:00
    https://gitlab.synchro.net/main/sbbs/-/commit/e7394337303a1c648f71532a
    Added Files:
    src/syncterm/scripts/auto/connected/scrollback_view.wren
    Modified Files:
    src/syncterm/CMakeLists.txt src/syncterm/SyncTERM.pbproj/project.pbxproj src/syncterm/SyncTERM.vcxproj bbslist.c objects.mk src/syncterm/scripts/auto/connected/keys_default.wren online_menu.wren src/syncterm/scripts/syncterm.wren wrentest.wren src/syncterm/term.c wren_bind.c wren_bind_conn.c wren_bind_screen.c wren_bind_screen.h wren_host.c wren_host_internal.h
    Removed Files:
    src/syncterm/menu.c menu.h
    Log Message:
    SyncTERM: move scrollback viewer to Wren, delete menu.c

    Replaces viewscroll() with scripts/auto/connected/scrollback_view.wren -
    a Fiber-driven modal that pushes the live cterm region into the
    scrollback ring, runs its own Input.next() pan loop (arrows / jklh /
    PgUp/PgDn / Home/End / wheel / drag-select / Esc / q), and pops the
    ring on exit. Help is a Pane-rendered markdown popup reached via F1.

    Wren bindings: new Scrollback foreign class behaves as a Surface via linearize-and-dispatch (in-place 3-reverse row rotation, no malloc'd
    copy) plus pushScreen / popScreen verbs that wrap the live cterm
    region into and out of the ring. Surface.urlAt(col, row) wraps
    detect_url_at. Scrollback.is(_) overrides so `Scrollback is Surface`
    is true. The previously-added Hyperlinks.open(id) primitive is
    removed; opening URLs from script bypassed the consent model that
    treats a real user click as the gating gesture.

    C side: handle_mouse_event() folds wheel-press into the existing
    button-2/3 conn_send block (preserving tracking-mode wheel-to-remote forwarding), with the Hook.onMouse(wheelUpPress) gate in
    scrollback_view.wren consuming wheel-press in OFF/RIP/X10 to enter
    the viewer. Conn.scrollback() now invokes ScrollbackView.run() via
    wrenCall, so menu.c is deleted entirely.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Tuesday, May 05, 2026 15:06:00
    https://gitlab.synchro.net/main/sbbs/-/commit/e7df5284f3a19f54e20cb468
    Modified Files:
    src/syncterm/scripts/auto/connected/online_menu.wren status_default.wren src/syncterm/scripts/sftp_app.wren syncterm.wren src/syncterm/wren_bind.c wren_bind_conn.c wren_bind_conn.h
    Log Message:
    SyncTERM: expose Alt key name to Wren; use it in menus + status bar

    Adds two foreign Host accessors that wrap the ALT_KEY_NAMEP /
    ALT_KEY_NAME3CH macros in syncterm.h so Wren-side labels can
    adapt to the Quartz Cmd-as-Alt mapping:

    Host.altKeyName -> "Alt" / "Command" (full word for help text)
    Host.altKeyShort -> "ALT" / "CMD" (3-char form for menus)

    Updates the user-visible labels:

    - status bar (status_default.wren) "ALT-Z menu" -> "%(altKeyShort)-Z
    menu", so it reads "CMD-Z menu" on macOS.
    - online menu (online_menu.wren) entries use altKeyShort throughout.
    Picked the short form deliberately: the widest entry is "Change
    Output Rate (xxx-Up/xxx-Down)" which is 36 chars with a 3-char
    prefix and would have overflowed a 40-column screen with the
    spelled-out "Command-". All connected menus must remain usable
    at 40 cols.
    - sftp_app help-text deflist terms use altKeyName ("Command-Q",
    "Command-S") since the body of a help popup has plenty of room
    and the spelled-out form reads better in prose context.

    X11 / Wayland / SDL / Win32 / curses are byte-identical to before
    on the help-text side ("Alt-Q") and shift only in case on the menu
    side ("Alt-B" -> "ALT-B"; same width).

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Thursday, May 07, 2026 16:09:00
    https://gitlab.synchro.net/main/sbbs/-/commit/f20886b395b1c6fe878bae55
    Added Files:
    src/syncterm/scripts/auto/connected/transfer_app.wren src/syncterm/scripts/ui_logview.wren ui_logview_test.wren ui_progress.wren ui_progress_test.wren src/syncterm/wren_bind_xfer.c wren_bind_xfer.h
    Modified Files:
    src/syncterm/CMakeLists.txt GNUmakefile Wren.adoc src/syncterm/scripts/syncterm.wren ui_demo.wren ui_style.wren wrentest.wren src/syncterm/term.c wren_bind.c wren_host.c
    Log Message:
    SyncTERM: move transfer-window UI to Wren

    Replace the C-side draw_transfer_window/transfer_complete plumbing
    and the per-protocol cprintf progress callbacks with a Wren
    TransferApp driven by a worker thread + bounded mailbox. C side
    runs each protocol on its own thread and pushes pre-formatted
    status lines through xfer_tick_lock/get/unlock; the main thread
    stays in TransferApp's modal loop, which composes ProgressBar and
    LogView widgets.

    Worker-to-main marshalling covers the two thread-unsafe UI paths: duplicate-file resolution and the YMODEM->XMODEM filename prompt
    fallback. All six protocol entry points (zmodem recv/send/batch,
    xmodem/ymodem recv/send/batch, cet recv) now flip binary mode and
    hand off to wren_run_transfer; lputs auto-routes via the mailbox
    when xfer_session_active().

    Drops ~1100 lines of C Ä the legacy log_ti/progress_ti/transw_ti
    windows, ask_overwrite, the per-protocol progress functions, and
    the cputs-into-window logging path.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Friday, May 08, 2026 21:16:00
    https://gitlab.synchro.net/main/sbbs/-/commit/4bff151e82908c31a779210b
    Added Files:
    src/syncterm/scripts/auto/connected/transfer_pick.wren
    Modified Files:
    src/syncterm/scripts/auto/connected/keys_default.wren online_menu.wren src/syncterm/scripts/syncterm.wren src/syncterm/term.c term.h wren_bind.c wren_bind_conn.c wren_bind_conn.h wren_bind_xfer.c wren_bind_xfer.h
    Log Message:
    SyncTERM: move begin_upload / begin_download to Wren

    Replace the C-side begin_upload() and begin_download() uifc dialogs
    with Wren UploadApp / DownloadApp classes Ä protocol picker uses
    ListView, file selection goes through Host.pickFile / pickFiles
    (uifc filepick wrapper), XMODEM filename via Prompt.

    Three new Transfer foreigns dispatch into the existing protocol
    entry points: Transfer.upload(kind, path, lastCh),
    Transfer.uploadBatch, Transfer.download. Kinds are stringly-typed
    ("zmodem", "ymodem-g", "xmodem-1k", "cet", ...) so the C side can
    fan out to the right xmodem_*/zmodem_*/cet_telesoftware_download
    call without exposing mode flag bits to Wren.

    The foreigns can't run wren_run_transfer directly Ä wrenCall is
    forbidden from inside a foreign method (wren.md 7). They record
    the user's choice in a single-slot xfer_pending struct and return
    immediately; xfer_drain_pending(), called from doterm() at C
    top-level, runs the actual dispatch. Auto-Z drains right after wren_run_upload_app() returns; Alt-D / Alt-U are picked up at the
    next outer-loop iteration.

    Hook.onKey for Alt-D / Alt-U lives in keys_default.wren (matches
    the Alt-B / Alt-C / Alt-X migration pattern). Conn.upload() and Conn.download() Wren foreigns are gone Ä online_menu now calls
    UploadApp.run / DownloadApp.run directly.

    Deletes ~210 lines of C: begin_upload, begin_download, the Alt-D /
    Alt-U switch cases in doterm(), fn_Conn_upload / fn_Conn_download.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Saturday, May 09, 2026 18:36:00
    https://gitlab.synchro.net/main/sbbs/-/commit/fe8b2f6258f746aafb9e0a57
    Added Files:
    src/syncterm/scripts/auto/connected/font_pick.wren
    Modified Files:
    src/syncterm/scripts/auto/connected/keys_default.wren online_menu.wren src/syncterm/scripts/syncterm.wren ui_list.wren src/syncterm/term.c term.h wren_bind.c wren_bind_conn.c wren_bind_conn.h wren_bind_fs.c wren_bind_fs.h wren_bind_screen.c wren_bind_screen.h
    Log Message:
    SyncTERM: move font_control to Wren

    Replace the C-side font_control() uifc dialog with a Wren FontApp
    class. The picker uses ListView over Font.name(0..count-1), with
    Insert keying into Host.pickFile + Font.load(file). Hook.onKey
    for Alt-F lives in keys_default.wren; online_menu's "Font Setup"
    entry now calls FontApp.run() instead of Host.fontControl().

    Two new foreigns:
    - CTerm.altFont / CTerm.altFont=(slot) Ä getter/setter for
    cterm->altfont[0]. Setter calls ciolib_setfont(slot, false, 1)
    and updates the cache.
    - Font.load(file) Ä takes a File foreign (not a path string) and
    extracts the path internally via the new wren_file_path() helper
    in wren_bind_fs. Keeping bare paths out of Wren preserves the
    consent-token model: only paths the user explicitly approved
    through a picker can be opened.

    Two pre-existing bugs surfaced by this work, fixed in passing:
    - ListView.preferredHeight returned the unbounded item count, so a
    pane with fitContent() over the 100+ populated font slots
    overflowed the screen. Cap it at screen height minus a chrome
    budget (ListView already scrolls).
    - ListView.handleKey_ didn't guard `cp` before `cp >= 0x20`, so any
    extended key with null codepoint (Insert, function keys, arrows)
    that fell through the explicit handlers crashed with
    "Null does not implement '>=(_)'".

    Deletes ~75 lines: font_control() in term.c, the Alt-F switch case
    in doterm(), fn_Host_fontControl() shim, Host.fontControl()
    declaration.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, June 28, 2026 12:34:00
    https://gitlab.synchro.net/main/sbbs/-/commit/c060d433df60ef5077b9c363
    Added Files:
    src/syncterm/scripts/auto/connected/host_popup.wren
    Modified Files:
    src/syncterm/Wren.adoc src/syncterm/scripts/ui_popup.wren ui_popup_test.wren src/syncterm/term.c wren_host.c wren_host.h wren_host_internal.h
    Log Message:
    Route terminal popups through Wren alerts

    Co-Authored-By: OpenAI Codex <codex@openai.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, July 19, 2026 13:28:00
    https://gitlab.synchro.net/main/sbbs/-/commit/78c47f4897fa64b70557d6b5
    Added Files:
    src/syncterm/scripts/auto/picker/file_picker.wren src/syncterm/scripts/syncterm_picker.wren src/syncterm/wren_bind_picker.c wren_bind_picker.h
    Modified Files:
    src/syncterm/CMakeLists.txt objects.mk src/syncterm/scripts/menu_theme.wren picker_bootstrap.wren syncterm.wren src/syncterm/wren_bind_fs.c wren_bind_internal.h wren_picker_host.c wren_picker_host.h
    Log Message:
    wren: route file selection through the picker VM

    Run file selection in a third persistent Wren VM so menu and
    connected scripts never execute the picker implementation directly.

    Expose only directory listings, path resolution, metadata, and a
    one-shot completion object to picker scripts. Preserve the existing
    single, directory, save, and cross-directory multi-select behavior.

    Carry create-versus-overwrite consent out of the picker explicitly.
    Save and restore screen, mouse, and cursor state in C, with input
    barriers on both ownership transitions.

    Keep picker errors inside a recovery screen where Escape cancels and
    Ctrl+` opens the picker-local REPL.

    Co-Authored-By: OpenAI Codex <noreply@openai.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, July 19, 2026 13:28:00
    https://gitlab.synchro.net/main/sbbs/-/commit/1ca9a7c2d626fbe600ea029d
    Modified Files:
    src/syncterm/scripts/auto/picker/file_picker.wren
    Log Message:
    wren: center the file picker pane

    Inset the picker frame by two columns on each side so its body is
    centered while the two-column right shadow occupies the remaining edge.

    Start the frame on the second row and leave the final row for its bottom shadow. This preserves the existing top line without unnecessarily
    shortening the file lists.

    Co-Authored-By: OpenAI Codex <noreply@openai.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, July 19, 2026 13:28:00
    https://gitlab.synchro.net/main/sbbs/-/commit/e8d5754b7f126d0a2e4c532e
    Modified Files:
    src/syncterm/scripts/auto/connected/font_pick.wren src/syncterm/scripts/menu_settings_ui.wren
    Log Message:
    wren: restore font picker options

    Match the custom-font editor with its C predecessor by enabling direct
    Path entry and leaving its size-specific mask editable.

    Restore the connected Alt+F loader to its original no-option behavior.
    Both Wren migrations had substituted literal bit 1, which locks the mask,
    for the distinct flags used by the previous callers.

    Co-Authored-By: OpenAI Codex <noreply@openai.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, July 19, 2026 13:28:00
    https://gitlab.synchro.net/main/sbbs/-/commit/3e5ea94e13fc40f66633e807
    Modified Files:
    src/syncterm/scripts/auto/picker/file_picker.wren
    Log Message:
    wren: keep picker lists visually active

    Render both the directory and file lists with the active picker palette, regardless of which list currently owns keyboard focus.

    Focus continues to control event routing and selection, but no longer
    recolors the other half of the file browser as an inactive pane.

    Co-Authored-By: OpenAI Codex <noreply@openai.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Tuesday, July 21, 2026 09:28:00
    https://gitlab.synchro.net/main/sbbs/-/commit/a50e69645ff75924840895fc
    Modified Files:
    src/syncterm/scripts/auto/menu/main_menu.wren
    Log Message:
    Allow menu console from submenus

    Register Ctrl+` directly in the App global keymap instead of through
    the main-menu binding helper. That helper intentionally ignores commands
    while a modal is open, causing the console shortcut to be consumed without opening the REPL in settings, help, and editor panes.

    Keep the top-level guard for ordinary menu commands while allowing the
    current modal to remain mounted behind the console.

    Co-Authored-By: OpenAI Codex <noreply@openai.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Thursday, July 23, 2026 20:26:00
    https://gitlab.synchro.net/main/sbbs/-/commit/8965e8be8e8ff9078b93ea53
    Modified Files:
    src/syncterm/scripts/auto/picker/file_picker.wren
    Log Message:
    wren: clarify invalid picker start paths

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