Files
endorphin-tessera-gui/README.md
T
codex-bot 8cb2bf8607
Verify Tessera GUI / verify (push) Successful in 7m38s
feat: execute Tessera UI source with embedded Aster
2026-10-20 03:35:46 +08:00

154 lines
7.0 KiB
Markdown

# Tessera
Tessera is a native desktop UI host embedding [Aster](vendor/aster/README.md).
Agents submit ordinary Endor source through a local namespace API. Aster parses,
compiles and executes it; `main` returns a Tessera UI object. Tessera extracts a
native tree, lays it out and draws it using the existing software renderer.
The initial page is empty.
## Source and library integration
`vendor/aster` is an unmodified Git submodule, pinned to an exact published commit.
Cargo path dependencies directly use its `frontend`, `compiler` and `core`
(library name `endor_core`) packages, which bring in `objects`. The Aster workspace
and history remain independent. See [vendor](vendor/README.md) for initialization
and version updates, and [src](src/README.md) for the implementation map.
The runtime now uses Aster's Reader, Parser, AST, Compiler and VM. Tessera's former
experimental `namespace` / `export scene` / `render` parser has been removed.
Host UI integration lives in Tessera; Aster needs no Tessera-specific changes.
Lyra CLI and Hestia Server are independent hosts and are not application dependencies.
## Native build and start
Use Rust 1.91 or newer. Initialize the source submodule following the dedicated
codex-bot SSH identity instructions in [vendor](vendor/README.md), then build:
```bash
git submodule update --init --recursive
cargo build --release --locked
./target/release/tessera
```
Cargo compiles the required Aster libraries together with Tessera. No separate
Aster build, service or deployment is required. Local builds download dependencies
from official crates.io; do not substitute a mirror. Docker and automated tests
are not used locally. On macOS this produces a native executable, not an `.app`
bundle or installer.
The API listens only on `127.0.0.1:4737`. Start integrations with its live guide:
```bash
curl http://127.0.0.1:4737/agent
```
## Submit Endor
The active namespace starts as `app.main`:
```text
GET /v1/namespaces/app.main/code
PUT /v1/namespaces/app.main/code
DELETE /v1/namespaces/app.main/code
```
Submit the [complete example](examples/hello.endor):
```bash
curl --request PUT --header 'Content-Type: text/plain; charset=utf-8' \
--data-binary @examples/hello.endor \
http://127.0.0.1:4737/v1/namespaces/app.main/code
```
A minimal program is:
```endor
function main(): View {
let title = ui.text("Hello Endor", 2, "#242422")
let rectangle = ui.rect(240, 80, 12, "#DCE8FF")
return ui.column(24, 12, title, rectangle)
}
```
The namespace comes from the request path. `ui` is a host global declared to
Aster's compiler and injected into the candidate VM. Function declarations,
helper calls, local variables, member reads and positional arguments use Aster's
existing language implementation. `View` is currently a syntactic annotation;
Tessera validates the actual returned object. This does not add syntax to Endor.
The sample file is client-side material; the API itself stores source by namespace.
## UI host API
All arguments are positional. Defaults below describe omitted trailing arguments,
not Endor keyword argument syntax.
| Member | Arguments and defaults |
| --- | --- |
| `ui.text` | String, integer size (default 1, range 1..8), color (default `#242422`) |
| `ui.rect` | Width, height, radius (default 0), color (default `#DCE8FF`) |
| `ui.column` | Padding, gap, followed by zero or more UI children |
| `ui.row` | Padding, gap, followed by zero or more UI children |
| `ui.spacer` | Size |
Colors are `#RRGGBB` or `#RRGGBBAA`. Dimensions are finite numbers in 0..1000000.
Aster keeps its exact numeric representation; conversion occurs only at the UI
boundary. Text uses the current bitmap renderer, with Chinese fonts still pending.
## Candidate execution and publication
A dedicated worker performs source parsing, AST budget checks, compilation,
module initialization and zero-argument `main` execution in a fresh VM. It checks
the returned UI node, extracts native data, builds and validates the frame, then
cleans up all VM roots. The window receives no VM handles. It relays out the owned
native tree during redraw and display scale changes without rerunning Endor.
The existing callback interface has no allocator access. Tessera therefore
preallocates at most 4096 real UI objects per candidate. Each is initialized once.
Constructors return those borrowed handles; Aster retains call results under its
existing rules. Native child data owns its own lifetime and contains no managed
VM edges. This bounded pool is for snapshot construction, not a persistent dynamic UI.
Limits are 1 MiB source, 10000 visited AST nodes with a 64-level visitor depth,
4096 constructed UI nodes, 64 UI levels, 10000 expanded layout visits and 16 KiB
per text. VM initialization and entry execution each have a 128-frame and 1000000-
instruction budget. Repeated children count again during layout, preventing a
small shared tree from expanding without bound. The build queue holds eight
pending requests.
GET reads the last successful source while the worker executes. PUT waits for its
result; a successful response includes submission and committed revision numbers.
Parsing, compilation, execution, argument or layout errors return 422 with
explanations and preserve the last successful document. Source diagnostics include
line, column and byte ranges; VM tracebacks currently identify function starts and
instruction offsets, not an exact source location for every instruction.
A newer accepted PUT invalidates older work. DELETE clears the document immediately
and invalidates both queued and executing candidates. Superseded requests return
409 and cannot republish their page. A full or unavailable queue returns 503;
rejected queue entries do not invalidate accepted work. Failed builds do not
increment the committed revision. A worker-caught panic discards the entire
candidate and returns 500, retaining the previous document.
This stage supports static snapshot UI. Event callbacks, persistent running VMs,
window-size language inputs and process isolation are future work. Worker threads,
source budgets and VM instruction limits are not a complete untrusted-code sandbox.
## Developer tools
Toggle the sidebar with Command-Option-I or F12 on macOS, Control-Shift-I or F12
on Windows/Linux. It displays Aster AST functions, bindings, calls and expressions.
Selection shows their ranges in the exact submitted source. Tessera does not
maintain a second language AST.
## Validation
Local native builds and window runs are allowed; do not run local automated tests
or Docker. [Remote CI](.gitea/README.md) on ces-control runs the existing renderer
checks and the new Aster execution, UI layout, source-range, lifetime, budget,
failed-update and deletion-invalidation regressions, plus Clippy.
The API regressions use actual HTTP requests, including DELETE while the worker
is occupied and a queued PUT is superseded.
Linux CI does not verify macOS window presentation. Aster has no standalone CI/CD; Lyra CI
explicitly validates the pinned engine itself. CI uses official Cargo sources
and standard HTTPS checkout without custom SSH secrets.