Imported from wischner/native (
AGENTS.md). Install upstream withnpx skills add wischner/native. Copyright stays with the author.
AGENTS.md
The working project brief for contributors and coding agents, and the map of every maintained Markdown document in this repository. It describes how the library is structured, how builds must be handled, what quality bar is expected, and which documents a code change obliges you to refresh.
Read this first
Every code change must leave the affected documents refreshed in the same commit. Documentation in this project describes the code as it exists now — not a roadmap, not a wish list. A commit that changes behavior and leaves the matching chapter, standard, note, or matrix stale is an incomplete commit. See Refresh obligations for the concrete mapping.
The two normative standards outrank everything else:
| Document | Why |
|---|---|
| docs/standards/ARCHITECTURE.md | The architectural requirements. 21 numbered sections; the book chapters expand them one by one. |
| docs/standards/CPP-CODING-STYLE.md | Mandatory C++ style: directory structure, naming, header/implementation split, file headers, function documentation, build and test rules. |
Part 1 — Project rules
Project intent
nativeis a modern C++ UI library.- The public surface must feel like pure C++, not like a wrapper around native APIs.
- Platform-specific and toolkit-specific code must stay behind the public interface.
- The library should remain small, readable, educational, and easy to reason about.
Architecture
The library implementation is organized into three layers:
-
Core C++ layer
- Located in
lib/native/ - Shared across all targets
- Contains portable logic such as geometry, events, windows, app flow, and graphics abstractions
- Located in
-
Platform layer
- Located in
lib/native/platforms/ - Handles operating-system-specific integration
- Examples: Windows, Linux, Haiku, macOS
- Located in
-
Toolkit layer
- Located in
lib/native/toolkits/ - Used when a platform needs a separate windowing or rendering backend
- Examples on Linux:
x11,sdl2,openmotif
- Located in
The src/ directory contains the vision application. It is a consumer of
the public library API and must not contain private library implementation.
Tests live in tests/, and developer automation in scripts/.
Library-owned path manipulation, traversal, metadata, and file publication
use the C++20 std::filesystem library; file contents use standard C++
streams. Do not add direct POSIX or C filesystem calls, shell command
construction, or OS-specific helpers for work covered by those facilities.
Public values that identify filesystem entries use
std::filesystem::path; filename patterns, extensions, and labels remain
text.
Descriptor, process, signal, and terminal operations use POSIX interfaces.
Native UI, standard-panel, system-icon, and known-folder APIs remain isolated
and allowed in their platform or toolkit layer where the C++ standard library
has no equivalent.
Public interface rules
- The public API is exposed through
include/native.h. include/native.hmust remain pure C++.- Do not expose native OS handles, toolkit types, or platform headers in the public API.
- User-facing classes must not contain platform-specific implementation details.
- Prefer clear, modern, lowercase API naming consistent with the current codebase.
Native state and bindings
- Every created
wndowns one opaque internal peer. Per-window backend state, including graphics caches, is stored by that peer and never in the public class definition. - Use
native::bindingsonly where a native callback or resource identifier must recover its library object. Keep those callback-facing bindings in toolkit or platformglobals.*files inside the relevant namespace. - Object-to-state compatibility names use the stateless internal
detail::peer_bindings; do not add another process-wide bidirectional map for a new window/control state type.
Build system rules
- The build system entry point is
CMakeLists.txt. - CMake toolchain files live in
scripts/cmake/. - Developer automation lives in purpose-specific directories under
scripts/, such asscripts/linux/,scripts/windows/, andscripts/macos/remote/. - Do not add a new top-level
Makefilefor normal project orchestration. - Builds use the Docker-backed CMake targets. macOS is the documented
exception: use
scripts/macos/remote/build.shfor CMake/AppleClang with the Apple SDK on the configured remote Mac; validate shared C++ with GCC/Docker first. Do not substitute an ad hoc host build. - The purpose of Docker is to make backend builds reproducible and independent of host package drift.
Docker targets
The top-level CMake project provides:
docker-x11docker-gemixdocker-gemix-gemd(same GEMix image, serialized libgem transport)docker-sdl2docker-openmotifdocker-openlookdocker-wmakerdocker-windocker-haiku
These targets use the following Docker images:
- X11:
wischner/gcc-x86_64-linux-x11 - GEMix:
wischner/gcc-x86_64-gemix:latest - SDL2:
wischner/gcc-x86_64-linux-sdl - OpenMotif:
wischner/gcc-x86_64-linux-motif - OPEN LOOK:
wischner/gcc-x86_64-linux-openlook - Window Maker:
wischner/gcc-x86_64-linux-window-maker - Windows MinGW-w64:
wischner/gcc-x86_64-windows-mingw-w64 - Haiku cross toolchain:
wischner/gcc-x86_64-haiku
Both GEMix build targets use the published wischner/gcc-x86_64-gemix:latest
image, which already contains the GEM v1.0.0 SDK built from commit
0df463d9ff4b4cbbdd0612ce700c9e11e5e33661: headers and Rasta-backend
libraries in /usr/local with gemix-* pkg-config files, plus gemd,
resgen, the GEM resources, and the recorded revision in
/opt/gemix/share/metadata/gem.version. Docker pulls the image on first use;
no local SDK image build and no sibling GEM checkout is needed.
The expected workflow is:
cmake -S . -B build/cmake
cmake --build build/cmake --target docker-gemix
cmake --build build/cmake --target docker-gemix-gemd
cmake --build build/cmake --target docker-x11
cmake --build build/cmake --target docker-sdl2
cmake --build build/cmake --target docker-openmotif
cmake --build build/cmake --target docker-openlook
cmake --build build/cmake --target docker-wmaker
cmake --build build/cmake --target docker-win
cmake --build build/cmake --target docker-haiku
docker-amiga-check is a separate runtime qualification target, not a library
backend. It uses the pinned wischner/gcc-m68k-amiga image recorded in CMake,
scripts/cmake/toolchain-amiga.cmake and build/amiga-toolchain/. Both C++20
threading and filesystem checks currently fail; no Amiga Vision binary or F5
launch configuration exists. The VS Code task exposes the same diagnostic.
Build directories
build/cmake/is the host-side CMake control tree.build/linux-x11/is the Docker-produced X11 build tree.build/linux-gemix/is the Docker-produced GEMix build tree.build/linux-gemix-gemd/is the separate libgem/gemd GEMix build tree.build/linux-sdl2/is the Docker-produced SDL2 build tree.build/linux-openmotif/is the Docker-produced OpenMotif build tree.build/linux-openlook/is the Docker-produced OPEN LOOK build tree.build/linux-wmaker/is the Docker-produced Window Maker build tree.build/windows-mingw-w64/is the Docker-produced Windows MinGW-w64 build tree.build/haiku/is the Docker-produced Haiku build tree.
Do not collapse multiple platform or toolkit builds into the same CMake build directory.
Linux backend rules
X11 backend
- Files under
lib/native/toolkits/x11/are for Xlib, Xt, and Athena code. - Use Athena widgets for standard controls and menus instead of emulating their painting and input behavior with custom Xlib windows.
- Do not include Motif headers in the X11 backend.
- If a file only needs Xlib/Xutil/XRandR types, include only the matching X11 headers.
- The Docker X11 image must provide Xt and Athena, and must compile the X11 backend without OpenMotif installed.
- The X11 F5 profile runs Docker GDB through
scripts/linux/x11/run-twm.shin a dedicated monochrome Xephyr/TWM display, never directly on the host desktop. The session's tools come from the X11 image, and it is scaled to the hostXft.dpi. Keep GDB/MI stdout clean and other backend profiles independent.
OPEN LOOK backend
- Build with
docker-openlook. F5 and standalone execution use thewischner/gcc-x86_64-linux-openlook:latestimage and itsopenlook-xephyrhelper, which supplies Xephyr and olwm. No Tribblix VM is required. - Keep GDB/MI stdout clean and use
scripts/linux/docker-debug.shfor F5, orscripts/linux/toolkit-session-run.sh openlookfor standalone runs.
SDL2 backend
- Files under
lib/native/toolkits/sdl2/are for SDL2 code only. SDL2_ttfis optional.- If
SDL2_ttfis not found, text drawing must degrade gracefully instead of breaking the build. - SDL2 paint flow must render at frame boundaries, not present once per primitive.
- Avoid repaint backlogs and laggy input paths; invalidation should be efficient.
- Default SDL2 windows should open in a reachable on-screen position.
OpenMotif backend
- Files under
lib/native/toolkits/openmotif/are for Motif/Xt integration only. - Keep Motif and Xt types out of
include/native.h. - Use widget or resource colors when available, so Motif environments such as CDE can provide the default look.
- If resource lookup fails, fall back to explicit defaults:
- paper = white
- ink = black
- Keep the X11/Athena backend independent from Motif headers and libraries.
Windows backend rules
- Files under
lib/native/platforms/windows/are for Win32 integration only. - Windows F5 runs
vision.exenatively in the Windows VM through thescripts/windows/vm/deployment and interactive-desktop debug scripts, not Wine. The Docker MinGW build remains the build source. - Keep Win32 handle types and message-loop details out of
include/native.h. - Mouse press/release/move/wheel events must map to the same
nativesemantics used by Linux backends. painterbehavior must match Linux stable backends:- press starts stroke
- move extends stroke
- release ends stroke
- wheel clears strokes
Haiku backend rules
-
Files under
lib/native/platforms/haiku/are for Haiku API integration only. -
Keep
BApplication,BWindow, andBViewusage behind the platform layer. -
Mouse press/release/move/wheel and paint invalidation flow must match Linux stable backends.
-
painterbehavior must match Linux stable backends:- press starts stroke
- move extends stroke
- release ends stroke
- wheel clears strokes
-
Optional Haiku GLSL uses dynamically loaded Mesa OSMesa, with native views unchanged. The verified Mesa 22.0.5 runtime uses GALLIUM_DRIVER=softpipe; its llvmpipe JIT is rejected before drawing. Keep driver selection in test, debug and deployment environments, never mutate it inside the library.
-
Haiku image context nesting owns its predecessor state and leaves in binding order. Foreign Mesa bindings are rejected unchanged before activation.
Vision program
visionis the single program built by the repository.- Its source lives in
src/and it links againstnativethrough the public API. - VS Code launch configurations should point to
visionfor each active backend. - Educational programs belong in docs/manuals/PROGRAMMING-NATIVE.md and its chapter files, not in a separate examples source tree.
Quality bar
- Prefer small, explicit, maintainable code over clever code.
- Match the style and architecture already present in the project.
- Fix root causes, not just symptoms.
- Keep toolkit and platform code isolated to their own directories.
- Do not let backend-specific hacks leak into the public API.
- When adding fallback behavior, make it explicit and predictable.
Part 2 — Documentation map
Top level
| Document | Contents |
|---|---|
| README.md | Project pitch, feature summary, backend list, dependency list per backend, direct and Docker-backed build commands, build output layout, and links into the two manuals. The public front door. |
| AGENTS.md | This file: project rules, documentation map, and refresh obligations. |
| docs/ADJUST.md | Dated standards review, completed non-Amiga repairs and verification, SDK exceptions, and excluded Amiga runtime blockers. A review record, not a new standard. |
Standards — docs/standards/
Normative. Short, rule-shaped, and authoritative when a book chapter and a standard appear to disagree.
| Document | Contents |
|---|---|
| ARCHITECTURE.md | Sections 1–21: code structure, native bindings, signals, setters/getters, windows, painting, custom drawing, application, screens, fonts, clipboard, text editing, advanced tables, source editing, classic trees, split views and tabs, filesystem resources/input controls/standard dialogs/non-client chrome, structural containers, paintable child surfaces, background delivery/audio/child ownership, and portable programmable image shaders. |
| CPP-CODING-STYLE.md | Sections 1–9: project directory structure, naming conventions, header and implementation separation, file header block, function documentation, general coding rules, build rules, documentation rules, and tests. |
The Book of Native — docs/manuals/book-of-native/
Explains how the library is built and why. It is the detailed companion to the architectural standards: most chapters name the Architecture section they expand. Index: docs/manuals/BOOK-OF-NATIVE.md — current scope, runtime-tested backend list, and the maintained chapter table of contents.
| Chapter | Contents |
|---|---|
| GETTING-STARTED.md | Build the project, run vision, and understand the output layout. |
| BUILD-SYSTEM.md | How top-level CMake and the Docker-backed backend targets are organized. |
| PATTERNS-LAYERING.md | Public API boundaries, the three implementation layers, and native handle/object mappings. Expands Architecture 1–2. |
| PATTERNS-GEOMETRY.md | Shared value types used by geometry, windows, graphics, and events. |
| PATTERNS-SIGNALS.md | Public event contracts, connection lifetimes, synchronous dispatch. Expands Architecture 3. |
| PATTERNS-PROPERTIES.md | Setter/getter naming, portable caches, native-originated updates. Expands Architecture 4. |
| PATTERNS-WINDOWS.md | Window state, hierarchy, lifecycle, layout, backend obligations. Expands Architecture 5. |
| PATTERNS-PAINTING.md | Graphics contexts, paint-event lifetimes, clipping, invalidation. Expands Architecture 6. |
| PATTERNS-THEME.md | Native theme primitives, semantic control states, portable fallbacks. Expands Architecture 7. |
| DRAWING-PRIMITIVES.md | Application-facing reference for window and image graphics, PNG/JPEG I/O, text measurement, and themed control drawing. |
| PATTERNS-APPLICATION.md | Portable startup through program(), app::run(), and backend launchers. Expands Architecture 8. |
| PATTERNS-SCREENS.md | Snapshot lifetime, work areas, primary selection, backend detection. Expands Architecture 9. |
| PATTERNS-FONTS.md | Stock/portable font ownership, byte-backed registration, measurement/rasterization and platform discovery. Expands Architecture 10. |
| PATTERNS-CLIPBOARD-TEXT-EDITING.md | Typed clipboard transactions, editor modes, live validation, selection, clipboard commands. Expands Architecture 11–12. |
| PATTERNS-TABLE-VIEW.md | Model ownership, stable row identity, virtualization, grouping, search, backend adaptation. Expands Architecture 13. |
| PATTERNS-CODE-EDIT.md | Canonical source storage, overlays, lexers, completion, shared painting, backend input translation. Expands Architecture 14. |
| PATTERNS-TREE-VIEW.md | Owned hierarchy, stable IDs, visible rows, selection/disclosure, native adapters and scrolling. Expands Architecture 15. |
| PATTERNS-SPLIT-VIEWS-AND-TABS.md | Split/tab layout ownership, native content transitions, floating shells, interaction, themed painting, persistence. Expands Architecture 16. |
| PATTERNS-INPUT-DIALOGS-WINDOW-CHROME.md | File icons, special directories, combo and list boxes, directory and message dialogs, non-client rulers, status bars, native adaptation, extensibility. Expands Architecture 17. |
| PATTERNS-PANELS-AND-CANVASES.md | Container versus drawing-surface roles, explicit child lifecycle, chrome versus client geometry, 32-bit content bounds, scrollbar resolution, painting order. Expands Architecture 18–19. |
| PATTERNS-BACKGROUND-SERVICES.md | Scoped UI delivery, bounded PCM peers, child ownership and shutdown. Expands Architecture 20. |
| PATTERNS-IMAGE-SHADERS.md | Immutable portable CPU image programs, typed properties, canvas composition, multipass/history, weak paced delivery and bounded execution. Expands Architecture 21. |
| FEATURE-MATRIX.md | Per-backend feature and test status for what is implemented now. |
Architecture Sections 10 (Fonts) and 15 (Classic trees) now have matching internal pattern chapters. The application-side references remain Drawing primitives and collection/disclosure controls.
Programming Native — docs/manuals/programming-native/
Teaches how to write applications against the library. Complete runnable programs and focused snippets; this is where educational example code lives instead of a separate examples source tree. Index: docs/manuals/PROGRAMMING-NATIVE.md — how a native program is organized, the 20-chapter table of contents, and build instructions.
| Chapter | Contents |
|---|---|
| 01-FIRST-APPLICATION.md | The smallest program: app_wnd passed to app::run(). |
| 02-PAINTING-AND-INPUT.md | Deriving a window class, paint events, mouse input. |
| 03-MENUS-AND-COMMANDS.md | The main_menu model, construction order, commands. |
| 04-BUTTONS.md | Control objects and the native-resource creation lifecycle. |
| 05-CONFIGURING-CONTROLS.md | Geometry constructors and post-creation changes. |
| 06-ABSOLUTE-LAYOUT.md | absolute_layout_manager. |
| 07-GRID-LAYOUT.md | grid_layout_manager, tracks, nesting. |
| 08-SELECTION-CONTROLS.md | check, radio, list. |
| 09-OWNED-WINDOWS-AND-DIALOGS.md | Owned/modeless/modal windows and standard file dialogs. |
| 10-GRAPHICS-IMAGES-FONTS-THEMES.md | The gpx drawing interface, images, fonts, themes. |
| 11-CLIPBOARD-AND-TEXT-EDITING.md | UTF-8 encoding boundary, clipboard, text controls. |
| 12-BUILDING-AND-DISTRIBUTING.md | The nine build selections (six Linux toolkits plus Windows, Haiku, macOS), linking, distribution. |
| 13-COLLECTION-AND-DISCLOSURE-CONTROLS.md | accordion, icon_view, tree_view. |
| 14-ADVANCED-TABLE-VIEWS.md | list versus table_view, models, virtualization. |
| 15-SOURCE-EDITING.md | code_edit: line numbers, syntax styles, source UTF-8. |
| 16-SPLIT-VIEWS-AND-TABS.md | split_view and native tab controls. |
| 17-INPUT-DIALOGS-AND-WINDOW-CHROME.md | File icons, special directories, choice controls, OS dialogs, non-client chrome. |
| 18-PANELS-AND-CANVASES.md | panel grouping and child lifecycle, canvas painting, scrolling, scrollbar policy, and rulers. |
| 19-BACKGROUND-WORK-AND-SERVICES.md | C++20 workers, scoped UI results, PCM output, child helpers and interactive acceptance. |
| 20-IMAGE-SHADERS.md | Shader-view lifecycle, source ownership, typed parameters, portable expression authoring/package format, fitting, animation, fallback and mouse acceptance. |
Notes — docs/notes/
Exceptional material only: remote builds, unusual host requirements, open issues, and TODO inventories. Standard local and Docker build instructions do not belong here — they belong in the book. Index: docs/notes/README.md, which states what qualifies.
| Document | Contents |
|---|---|
| CUSTOM.md | Native-versus-custom control audit. Per backend, per public control: native (N), hybrid (H), library-painted (C), or external helper (E), plus applied native replacements and deliberately retained custom implementations with reasons. Carries an audit date. |
| REFACTOR.md | Deferred review of splitting the large theme interface; records the measured concern, proposed grouping, and evidence threshold for implementing it. |
| INFINITY.md | Infinity/nemu migration, implemented input/audio/background/process contracts, manual acceptance entry point and outstanding GEM/macOS verification constraints. |
| MOUSE-AND-SHADERS-REVIEW.md | Review of Infinity's proposed pointer and shader contracts against Native naming, ownership, lifecycle, composition, and verification requirements. No implementation claim. |
| BACKEND-OPEN-ISSUES.md | Backend-level issues that are real today, plus the runtime-tested versus in-progress backend status. |
| HAIKU-REMOTE-RUNTIME.md | Haiku workflow: Docker cross-build, scp deploy, GDB over ssh, and what is verified. |
| MACOS-REMOTE-RUNTIME.md | Remote macOS workflow from Linux against host leia, MAC_REMOTE_* settings, driving scripts, AppKit/GLSL regression and sanitizer commands, desktop permissions, and visual-coverage limits. |
| WINDOWS-WINE-RUNTIME.md | Which MinGW runtime DLLs must sit next to the .exe for docker-win binaries to run under Wine. |
| WINDOWS-VM-RUNTIME.md | Native Windows 11 VM deployment, key-only SSH, interactive desktop GDBserver and the F5 tunnel lifecycle. |
| PRODUCTION-SOURCE-TODOS.md | Inventory of TODO markers in include/, lib/native/, and src/. Must be updated in the same commit that adds or removes a production TODO. |
| LAB-SOURCE-TODOS.md | Inventory of TODOs in the legacy lab/ tree. That tree is not currently present in the repository; treat this note as historical until it returns or is removed. |
Other
| Document | Contents |
|---|---|
| src/assets/retro-terminal/README.md | Pinned upstream shader/font provenance, GPL/CC-BY-SA notices, selected CPU port differences and executable asset deployment. |
| lib/native/third_party/README.md | Provenance and pinned upstream commit for the vendored stb_truetype.h, and its exemption from local formatting and file-length conventions. |
Part 3 — Documentation obligations
Refresh obligations
Documentation must be refreshed in the same commit as the code change that invalidates it. Use this table to find what a change touches.
| If you change… | Refresh |
|---|---|
Public API in include/native.h |
The relevant ARCHITECTURE.md section, the book chapter that expands it, and the Programming Native chapter that teaches it. |
| A control's implementation on any backend | CUSTOM.md (kind mark and audit date) and FEATURE-MATRIX.md. |
| Backend feature coverage or test status | FEATURE-MATRIX.md and, if the runtime status changed, README.md, BOOK-OF-NATIVE.md "Current scope", and BACKEND-OPEN-ISSUES.md. |
| Build paths, CMake targets, or Docker images | README.md, the build system rules in Part 1 of this file, GETTING-STARTED.md, BUILD-SYSTEM.md, 12-BUILDING-AND-DISTRIBUTING.md, and .vscode/launch.json / .vscode/tasks.json. |
| Architectural layering or binding rules | ARCHITECTURE.md, the architecture rules in Part 1 of this file, and PATTERNS-LAYERING.md. |
The wnd base contract — geometry derivation, paint sequence, hierarchy, or a new protected hook |
ARCHITECTURE.md Section 5, PATTERNS-WINDOWS.md, PATTERNS-PAINTING.md, and any chapter describing a control that overrides the hook. Every window type inherits the change, so the sweep is wider than the control that motivated it. |
| Add or move a test executable | BUILD-SYSTEM.md test table, and tests/CMakeLists.txt. |
| Add or remove a TODO in production source | PRODUCTION-SOURCE-TODOS.md. |
| A remote or unusual host workflow | The matching note in docs/notes/, and its entry in docs/notes/README.md. |
| A vendored third-party file | lib/native/third_party/README.md. |
Every new control, and every existing control added to another backend, must
record its N, H, C, or E kind in CUSTOM.md in the same
commit. Every C entry must also have a concrete justification in the
reviewed-proposals table; an unexplained custom implementation is a defect.
Documentation conventions
- Keep docs aligned with the actual build flow.
- Markdown file names use uppercase words separated by hyphens with a
lowercase
.mdsuffix, for exampleBACKEND-OPEN-ISSUES.md. Conventional single-word names such asREADME.mdremain valid. - BOOK-OF-NATIVE.md and
docs/manuals/book-of-native/describe how the current code works; they are not a roadmap. No speculative features, no future plans, no "coming soon". - If a feature is not implemented, leave it out until the code exists.
- Prefer backend-agnostic explanations in the book when the same pattern is shared.
- Use
docs/notes/only for exceptional cases such as remote builds or unusual host requirements. Do not keep normal Docker build instructions there. - Do not maintain generated API docs;
docs/apistays absent until that work is intentionally started. - Adding a new note also means adding its line to docs/notes/README.md; adding a chapter also means adding it to its manual's table of contents — and adding either means adding a row to the documentation map above.
High-quality contributor prompts
Use prompts like these when asking an agent or contributor to work on the codebase. They are intentionally specific and should be preferred over vague requests.
Build and infrastructure
- "Update the top-level CMake workflow so Linux X11 and SDL2 builds run through the Docker-backed targets, and keep VS Code debug tasks aligned with the same paths."
- "Refactor the Linux build output layout so toolkit-specific builds live under
build/linux-*without breaking the Docker CMake targets or debugger launch paths."
General feature work
- "Implement the feature inside the correct layer: core logic in
lib/native/, OS integration inlib/native/platforms/, toolkit behavior inlib/native/toolkits/, and keep the public headers ininclude/pure C++." - "When changing build or backend behavior, update the code, docs, and VS Code launch/build integration together."
Vision's terminal acceptance mode keeps its attributed shader/font assets under
src/assets/retro-terminal/. Copy the complete directory beside the deployed
binary; its asset README records upstream revision, licenses and port limits.
