[READ-ONLY] Mirror of https://github.com/bombshell-dev/tty. Platform independent 2D layout engine for terminal applications based on Clay bomb.sh/docs/tty
tty AGENTS.md
2.9 kB
Markdown
at main

AGENTS.md #

Spec-driven development #

  • Specs in specs/ are the source of truth. Code conforms to specs, not the other way around.

  • Never add, remove, or change a public API in code without first updating the relevant spec and getting explicit approval from the user. This includes changes to Term, createTerm, render(), directive constructors (open, close, text), sizing helpers (grow, fixed, fit), and any future spec'd interfaces.

  • The workflow is: propose the spec change, wait for approval, then implement. Do not combine spec changes with implementation in a single step.

  • The renderer and input parser are specified separately (renderer-spec.md and input-spec.md). They are architecturally independent. Do not introduce dependencies between them.

  • Specs describe what is. No "current", "earlier", or "planned" language; differences from prior versions go in commits and PR descriptions.

  • No code change lands with its spec out of date.

  • Each test file tests exactly one spec. Do not put tests for one spec into another spec's test file.

  • Layout tests assert ASCII pictures of the grid (expect(trim(print(ansi, w, h))).toEqual(...)), not raw bytes.

Commit and PR conventions #

Before opening a PR, check the change against docs/review-patterns.md and run deno task fmt.

Do not include any agent marketing material (e.g. "Generated with...", "Co-Authored-By: <agent>") in commits, pull requests, issues, or comments.

Rendering invariants #

  • The renderer MUST NOT perform IO. It produces bytes; the caller writes them.

  • The renderer MUST NOT manage terminal state (alternate buffer, mouse reporting, keyboard protocol modes). Cursor visibility and positioning are renderer-managed only when a caret declaration is present on a text() directive (see renderer-spec.md §7.6). The mouse pointer shape is renderer-managed only while the pointerShape capability is true (see renderer-spec.md §7.10).

  • Each frame is a complete snapshot. The renderer carries no UI tree state between frames — only cell buffers for diffing.

  • Public API values are string literals ("center-center"), not numeric constants or enums. Use functions when a value is parameterized.

  • Directives are plain objects. No classes, no methods, no prototype chains. The flat array pattern is normative.

C code conventions #

  • No global mutable state. All state belongs on a struct instance (e.g. Clayterm). Use Clay's userData pointer or similar mechanisms to route callbacks back to the owning instance.

  • Renderer state (e.g. capabilities) lives in native state. Do not copy it across the JS/WASM boundary on every call.

  • Never fabricate a default for unknown input. On overflow, keep structures balanced and report through the error channel; never silently corrupt or truncate.