• 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