# AGENTS.md This file is the quick-start map for agents working in this repository. Keep it small and point to the live docs instead of duplicating the whole plan. ## Current Modernization Goal PanoPainter is being incrementally modernized into independently testable C++23 components while preserving current behavior. OpenGL remains the working backend until the renderer boundary is proven; Vulkan/Metal/WebGPU work waits behind that boundary. Read these first: - `docs/modernization/roadmap.md` - live phase roadmap, recent results, and next work queue. - `docs/modernization/debt.md` - required debt log. Every temporary adapter, retained legacy dependency, skipped platform, fallback, or shortcut needs an entry with validation and removal conditions. - `docs/modernization/capability-map.md` - behavior that must be preserved. - `docs/modernization/build-inventory.md` - current build/component inventory. - `docs/adr/0001-modernization-boundaries.md` - component boundary decisions. ## Working Rules - Work on `codex/modernization-cmake-foundation` unless the user says otherwise. - Commit and push each verified successful progress slice. - Prefer larger coherent slices over tiny checkpoints, but keep docs/debt updated with each slice. - After a verified slice is committed and pushed, reset conversation context before starting the next slice when practical, especially if the thread is approaching automatic compaction. Record all needed resume state in committed code/docs first so the next thread can restart from `AGENTS.md`, roadmap/debt, and git history instead of relying on chat transcript context. - Do not revert user changes. Unrelated untracked notes, such as `docs/human-review-notes.md`, should be left alone unless explicitly requested. - Use CMake as the source of truth. Legacy Visual Studio project files are not the modernization path. - Use `apply_patch` for manual source/doc edits. ## Build And Test Primary Windows configure/build: ```powershell cmake --preset windows-msvc-default cmake --build --preset windows-msvc-default --config Debug --target PanoPainter pano_cli ``` Quiet checkpoint validation, preferred when working through Codex token-limited sessions: ```powershell powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter,pano_cli -TestRegex "pp_app_core|pano_cli_plan" ``` The quiet wrapper writes full command logs under `out/logs/quiet-validation`, prints only a compact summary, and applies editable warning/noise filters from `scripts/automation/quiet-validation-ignore.txt`. If a step fails, read the reported log file instead of rerunning with verbose output. Focused fast validation: ```powershell ctest --preset desktop-fast --build-config Debug --output-on-failure ``` Useful targeted pattern: ```powershell ctest --preset desktop-fast --build-config Debug -R "pp_app_core|pano_cli_plan" --output-on-failure ``` Apple compile validation runs through the Mac mini SSH alias `panopainter-mac`: ```powershell powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.ps1 -Presets macos,ios-simulator,ios-device ``` This is a headless component/test/tool compile gate for macOS, iOS simulator, and iOS device. Signed Apple bundles remain tracked in the debt log. If MSVC reports corrupt debug information or stale PDB/object errors, clean the generated build tree target before judging source changes: ```powershell cmake --build --preset windows-msvc-default --config Debug --target clean ``` ## Code Navigation Codex has a repo-specific skill named `panopainter-code-navigation`. Agents must use it when necessary: follow this path before broad text search when a task is about C++ symbol identity, symbol families, declarations/definitions, override groups, or platform/backend boundaries. Use it when following C++ symbols, finding symbol families with regular expressions, tracing service/interface wiring, or checking platform/backend boundary usage. Reach for `--name-regex`, `--detail-regex`, or `--path-regex` when looking for generated-style name families, override groups, command/service families, signatures, or platform/backend path slices. Use normal `rg` for docs, build files, comments, string literals, generated command names, or exact non-C++ text. Prefer compiler-aware navigation when following C++ symbols across the legacy flat source tree and extracted components: ```powershell python scripts/dev/clangd_nav.py symbols --file src/app_core/brush_ui.h --name execute_brush python scripts/dev/clangd_nav.py symbols --file src/app_core/brush_ui.h --name-regex "execute_.*preset" python scripts/dev/clangd_nav.py symbols --file src/app_core/document_export.h --detail-regex "Export.*Plan" python scripts/dev/clangd_nav.py definition --file src/node_panel_brush.cpp --line 511 --column 39 python scripts/dev/clangd_nav.py references --file src/app_core/brush_ui.h --line 783 --column 45 --path-regex "src[\\/]app_core" python scripts/dev/clangd_nav.py self-test ``` The helper talks to `clangd` using an existing `compile_commands.json`. It defaults to `out/build/windows-clangcl-asan` and then `out/build/android-arm64`; pass `--compile-commands-dir` or set `PP_CLANGD_COMPILE_COMMANDS_DIR` when using another Ninja build tree. Use `--name` and `--max-results` to keep output small. Use `--name-regex` for regex filtering against `qualifiedName`, `--detail-regex` for symbol detail/signature filtering, and `--path-regex` for definition/declaration/implementation/reference location filtering. Regex matching is case-insensitive by default, and `--no-ignore-case` makes it case-sensitive. Run `python scripts/dev/clangd_nav.py self-test` or the `panopainter_clangd_nav_regex_self_test` CTest before relying on regex behavior after tool changes. Treat symbol, hover, declaration, definition, and implementation lookups as the reliable path. Reference lookups are riskier because a one-shot clangd process may not have a complete project index; the helper refuses reference queries unless callers pass `--background-index` for broader best-effort results or `--allow-incomplete-references` for explicitly current-translation-unit-only results. Do not use incomplete reference output as proof that a symbol has no other users. ## Current Architecture Direction The desired component split is documented in the roadmap. Current extracted or in-progress boundaries include: - `pp_foundation` - `pp_assets` - `pp_paint` - `pp_document` - `pp_renderer_api` - `pp_renderer_gl` - `pp_paint_renderer` - `pp_app_core` - `pp_panopainter_ui` - `pp_platform_*` - `panopainter_app` Legacy UI/app code still exists and is being reduced through pure planners, service interfaces, CLI automation, and CTest coverage. When moving behavior out of a legacy node, preserve current behavior first, add focused tests, document remaining shortcuts in `docs/modernization/debt.md`, then wire the live adapter. ## Legacy Context PanoPainter started as a flat C++17 OpenGL panoramic painting app centered on singletons such as `App::I`, `Canvas::I`, `Settings`, and `WacomTablet::I`. Rendering uses GLAD/OpenGL and shaders in `data/shaders/`. UI is XML/Yoga based with many `Node*` subclasses. Project files are PPI, brush packages are PPBR, and Photoshop brushes import through ABR support. Exceptions are disabled in app code. Public modernization APIs should return explicit status/result objects.