154 lines
7.0 KiB
Markdown
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.
|