https://gitlab.synchro.net/main/sbbs/-/commit/bdd490904e413f949158803e
Added Files:
src/syncterm/WrenTODO.md
Modified Files:
src/syncterm/Wren.adoc src/syncterm/scripts/auto/connected/sftp_pubkey.wren src/syncterm/scripts/sftp_app.wren sftp_queue.wren syncterm.wren ui_app.wren ui_button_test.wren ui_checkbox_test.wren ui_demo.wren ui_draw_test.wren ui_form_test.wren ui_help_test.wren ui_input_test.wren ui_list.wren ui_list_test.wren ui_menubar.wren ui_menubar_test.wren ui_popup_test.wren ui_radio.wren ui_radio_test.wren ui_spinbox_test.wren ui_statusbar_test.wren ui_style_test.wren ui_widget.wren ui_widget_test.wren wrentest.wren src/syncterm/wren_bind.c wren_bind_conn.c wren_bind_conn.h wren_bind_fs.c wren_bind_fs.h wren_bind_internal.h wren_bind_screen.c wren_bind_screen.h wren_bind_sftp.c wren_bind_won.c wren_bind_won.h wren_host.c wren_host_internal.h
Log Message:
SyncTERM: Wren API alpha-polish pass
Working from the WrenTODO.md audit, applied the resolutions across
sections A-E that landed as code or documentation changes. Every
item is recorded in WrenTODO.md with its rationale + the
alternatives considered and rejected.
Highlights:
Errors
- Polymorphic `Error` / `ScriptError` base; `FileError`, `WONError`,
`ConnError` mirror `SFTPError`'s shape. Bucket B/C abort sites
converted to typed errors; OOM stays as abort.
API consistency
- `SFTP.read(fiber, handle, count, offset)` swapped to match
`File.readBytes(count, offset)`. `Conn.recv`/`peek` parameter
renamed to `count`.
- `Host.uploadDir` removed; replaced with `Host.uploadPath` (String).
All uploads now go through `Host.pickFile` / `Host.pickFiles`
(consent-token-backed); `sftp_queue` requires a token.
- `Container.focusedIndex` / `ListView.selected` /
`MenuBar.focusedItem` / `RadioGroup.selected`+`cursor` use `null`
for "nothing selected" instead of `-1` at the API boundary.
App + screen lifecycle
- `Screen.modalRun(fn)` — atomic Screen.save + CTerm.suspended +
restore wrapper; `sftp_app.run` and 10 ui_demo methods converted.
- `App.releaseFocus` / `App.restoreFocus` — defocus the App's
foreground tree around blocking host UIs (filepicker) so the
underlying widgets aren't drawn focused while another widget owns
the screen.
- `CustomCursor.preserve(fn)` / `VideoFlags.preserve(fn)` snapshot
helpers; both classes' static-vs-instance distinction documented
with the chained-static-writes non-atomicity caveat.
Sequence / data shape
- `Console.entries` Sequence view (Console itself stays static;
Sequence helpers need an instance).
- `Surface.rows` / `Surface.cols` Sequence-of-Sequence views; row-
major linear iteration order pinned in docs.
- `Cell.eqContent(other)` named structural-equality method (NOT a
`==` override — Cell stays foreign-identity-equal); ignores the
BG dirty bit, false if either cell flies pixel-graphics.
Doc reframes
- Async pattern (`||`-yield) presented as the canonical idiom with
the three single-source-fiber providers (hook handler / SFTP queue
worker / `App.runChild` child) listed up-front.
- `Hyperlinks` documented as a typed-ID lookup, NOT a Map (foreigns
cannot be Map keys per `wren_value.h:880-888`).
- `Cell` / `CTerm` accessor relationship clarified (different
scopes, not duplicate views).
- `toString` on debug-decorated classes documented as not-part-of-
the-contract once, up front under `== Object Model`.
Wrentest gained ~18 cases covering the new APIs and the null-
boundary changes.
Co-Authored-By: Claude Opus 4.7 (1M context) <
noreply@anthropic.com>
---
■ Synchronet ■ Vertrauen ■ Home of Synchronet ■ [vert/cvs/bbs].synchro.net