BBS:      TELESC.NET.BR
Assunto:  src/syncterm/WrenTODO.mdsrc/syncterm/Wren.adoc src/syncterm/scripts/au
De:       Deuc¨
Data:     Sun, 3 May 2026 00:25:42 -0700
-----------------------------------------------------------
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) 
n
---
  mSynchronetn  hgVertrauen n hHome of Synchronet n gh[vert/cvs/bbs].synchro.net

-----------------------------------------------------------
[Voltar]