···33333434- Directives are plain objects. No classes, no methods, no prototype chains. The
3535 flat array pattern is normative.
3636+3737+## C code conventions
3838+3939+- No global mutable state. All state belongs on a struct instance (e.g.
4040+ `Clayterm`). Use Clay's `userData` pointer or similar mechanisms to route
4141+ callbacks back to the owning instance.
+20-1
specs/renderer-spec.md
···631631### 12.3 Render return type
632632633633The `render()` method currently returns a `RenderResult` object shaped as
634634-`{ output: Uint8Array, events: PointerEvent[], info: RenderInfo }`.
634634+`{ output: Uint8Array, events: PointerEvent[], info: RenderInfo, errors: ClayError[] }`.
635635636636The `output` field is the ANSI byte output specified normatively in Section 7.3
637637and Section 8.2.
···670670671671Querying an element with an empty-string id or an id not present in the frame
672672returns `undefined`.
673673+674674+The `errors` field contains any errors reported by the Clay layout engine during
675675+the most recent `render()` call. Each error is a `ClayError` object with:
676676+677677+- `type`: a string identifying the error category. The following types are
678678+ defined, matching Clay's error taxonomy:
679679+ - `"TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED"`
680680+ - `"ARENA_CAPACITY_EXCEEDED"`
681681+ - `"ELEMENTS_CAPACITY_EXCEEDED"`
682682+ - `"TEXT_MEASUREMENT_CAPACITY_EXCEEDED"`
683683+ - `"DUPLICATE_ID"`
684684+ - `"FLOATING_CONTAINER_PARENT_NOT_FOUND"`
685685+ - `"PERCENTAGE_OVER_1"`
686686+ - `"INTERNAL_ERROR"`
687687+ - `"UNBALANCED_OPEN_CLOSE"`
688688+- `message`: a human-readable string describing the error in detail.
689689+690690+Errors are collected per-render; each call to `render()` returns only the errors
691691+from that invocation. The array is empty when no errors occurred.
673692674693The return type of `render()` has changed twice since the project's inception
675694(string, then `Uint8Array`, then `RenderResult`). While the ANSI bytes
+35-2
src/clayterm.c
···77 * output — pointer to output byte buffer
88 * length — length of output byte buffer
99 * measure — Clay text measurement callback
1010+ * error_count, error_type, error_message_length, error_message_ptr
1111+ * — per-render Clay error accessors
1012 */
11131214#include "clayterm.h"
···34363537/* ── Instance state ───────────────────────────────────────────────── */
36383939+#define MAX_ERRORS 32
4040+3741struct Clayterm {
3842 int w, h;
3943 Cell *front;
···4448 /* clip region */
4549 int clipx, clipy, clipw, cliph;
4650 int clipping;
5151+ /* error collection */
5252+ Clay_ErrorData errors[MAX_ERRORS];
5353+ int error_count;
4754};
48554956/* Memory layout inside the arena provided by the host:
···399406 + align64(clay_bytes); /* Clay arena */
400407}
401408402402-static void clay_error(Clay_ErrorData err) { (void)err; }
409409+static void clay_error(Clay_ErrorData err) {
410410+ struct Clayterm *ct = (struct Clayterm *)err.userData;
411411+ if (ct->error_count < MAX_ERRORS) {
412412+ ct->errors[ct->error_count++] = err;
413413+ }
414414+}
415415+416416+int error_count(struct Clayterm *ct) { return ct->error_count; }
417417+418418+int error_type(struct Clayterm *ct, int index) {
419419+ if (index < 0 || index >= ct->error_count)
420420+ return -1;
421421+ return (int)ct->errors[index].errorType;
422422+}
423423+424424+int error_message_length(struct Clayterm *ct, int index) {
425425+ if (index < 0 || index >= ct->error_count)
426426+ return 0;
427427+ return ct->errors[index].errorText.length;
428428+}
429429+430430+int error_message_ptr(struct Clayterm *ct, int index) {
431431+ if (index < 0 || index >= ct->error_count)
432432+ return 0;
433433+ return (int)ct->errors[index].errorText.chars;
434434+}
403435404436struct Clayterm *init(void *mem, int w, int h) {
405437 struct Clayterm *ct = (struct Clayterm *)mem;
···413445 Clay_Arena arena =
414446 Clay_CreateArenaWithCapacityAndMemory(clay_bytes, clay_mem);
415447 Clay_Initialize(arena, (Clay_Dimensions){(float)w, (float)h},
416416- (Clay_ErrorHandler){clay_error, 0});
448448+ (Clay_ErrorHandler){clay_error, ct});
417449418450 *ct = (struct Clayterm){
419451 .w = w,
···437469438470void reduce(struct Clayterm *ct, uint32_t *buf, int len, int mode, int row) {
439471 int i = 0;
472472+ ct->error_count = 0;
440473441474 Clay_BeginLayout();
442475