fix(linux): add missing yaze_gfx_render dependency to yaze_gfx_debug
Fixes linker error on Linux where yaze_gfx_debug.a (performance_dashboard.cc) was calling AtlasRenderer::Get() and AtlasRenderer::GetStats() but wasn't linking against yaze_gfx_render which contains atlas_renderer.cc. Root cause: yaze_gfx_debug was only linking to yaze_gfx_types and yaze_gfx_resource, missing the yaze_gfx_render dependency. This also fixes the undefined reference errors for HttpServer methods which were already properly included in the agent.cmake source list. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
45
AGENTS.md
Normal file
45
AGENTS.md
Normal file
@@ -0,0 +1,45 @@
|
||||
## Inter-Agent Collaboration Protocol
|
||||
|
||||
Multiple assistants may work in this repository at the same time. To avoid conflicts, every agent
|
||||
must follow the shared protocol defined in
|
||||
[`docs/internal/agents/coordination-board.md`](docs/internal/agents/coordination-board.md).
|
||||
|
||||
### Required Steps
|
||||
1. **Read the board** before starting a task to understand active work, blockers, or pending
|
||||
requests.
|
||||
2. **Append a new entry** (format described in the coordination board) outlining your intent,
|
||||
affected files, and any dependencies.
|
||||
3. **Respond to requests** addressed to your agent ID before taking on new work whenever possible.
|
||||
4. **Record completion or handoffs** so the next agent has a clear state snapshot.
|
||||
5. For multi-day initiatives, fill out the template in
|
||||
[`docs/internal/agents/initiative-template.md`](docs/internal/agents/initiative-template.md) and
|
||||
link it from your board entry instead of duplicating long notes.
|
||||
|
||||
### Agent IDs
|
||||
Use the following canonical identifiers in board entries and handoffs (see
|
||||
[`docs/internal/agents/personas.md`](docs/internal/agents/personas.md) for details):
|
||||
|
||||
| Agent ID | Description |
|
||||
|-----------------|--------------------------------------------------|
|
||||
| `CLAUDE_CORE` | Claude agent handling general editor/engine work |
|
||||
| `CLAUDE_AIINF` | Claude agent focused on AI/agent infrastructure |
|
||||
| `CLAUDE_DOCS` | Claude agent dedicated to docs/product guidance |
|
||||
| `GEMINI_AUTOM` | Gemini agent focused on automation/CLI/test work |
|
||||
| `CODEX` | This Codex CLI assistant |
|
||||
| `OTHER` | Any future agent (define in entry) |
|
||||
|
||||
If you introduce a new agent persona, add it to the table along with a short description.
|
||||
|
||||
### Helper Scripts
|
||||
Common automation helpers live under [`scripts/agents/`](scripts/agents). Use them whenever possible:
|
||||
- `run-gh-workflow.sh` – trigger GitHub workflows (`ci.yml`, etc.) with parameters such as `enable_http_api_tests`.
|
||||
- `smoke-build.sh` – configure/build a preset in place and report how long it took.
|
||||
- `run-tests.sh` – configure/build a preset and run `ctest` (`scripts/agents/run-tests.sh mac-dbg --output-on-failure`).
|
||||
- `test-http-api.sh` – poll the `/api/v1/health` endpoint once the HTTP server is running.
|
||||
|
||||
Log command results and workflow URLs on the coordination board so other agents know what ran and where to find artifacts.
|
||||
|
||||
### Escalation
|
||||
If two agents need the same subsystem concurrently, negotiate via the board using the
|
||||
`REQUEST`/`BLOCKER` keywords. When in doubt, prefer smaller, well-defined handoffs instead of broad
|
||||
claims over directories.
|
||||
295
CLAUDE.md
Normal file
295
CLAUDE.md
Normal file
@@ -0,0 +1,295 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
> **Coordination Requirement**
|
||||
> Before starting or handing off work, read and update the shared protocol in
|
||||
> [`docs/internal/agents/coordination-board.md`](docs/internal/agents/coordination-board.md) as
|
||||
> described in `AGENTS.md`. Always acknowledge pending `REQUEST`/`BLOCKER` entries addressed to the
|
||||
> Claude persona you are using (`CLAUDE_CORE`, `CLAUDE_AIINF`, or `CLAUDE_DOCS`). See
|
||||
> [`docs/internal/agents/personas.md`](docs/internal/agents/personas.md) for responsibilities.
|
||||
|
||||
## Project Overview
|
||||
|
||||
**yaze** (Yet Another Zelda3 Editor) is a modern, cross-platform ROM editor for The Legend of Zelda: A Link to the Past, built with C++23. It features:
|
||||
- Complete GUI editor for overworld, dungeons, sprites, graphics, and palettes
|
||||
- Integrated Asar 65816 assembler for ROM patching
|
||||
- SNES emulator for testing modifications
|
||||
- AI-powered CLI tool (`z3ed`) for ROM hacking assistance
|
||||
- ZSCustomOverworld v3 support for enhanced overworld editing
|
||||
|
||||
## Build System
|
||||
|
||||
- Use the presets defined in `CMakePresets.json` (debug: `mac-dbg` / `lin-dbg` / `win-dbg`, AI:
|
||||
`mac-ai` / `win-ai`, release: `*-rel`, etc.). Add `-v` for verbose builds.
|
||||
- Always run builds from a dedicated directory when acting as an AI agent (`build_ai`, `build_agent`,
|
||||
…) so you do not interfere with the user’s `build`/`build_test` trees.
|
||||
- Treat [`docs/public/build/quick-reference.md`](docs/public/build/quick-reference.md) as the single
|
||||
source of truth for commands, presets, testing, and environment prep. Only reference the larger
|
||||
troubleshooting docs when you need platform-specific fixes.
|
||||
|
||||
### Test Execution
|
||||
|
||||
```bash
|
||||
# Build tests
|
||||
cmake --build build --target yaze_test
|
||||
|
||||
# Run all tests
|
||||
./build/bin/yaze_test
|
||||
|
||||
# Run specific categories
|
||||
./build/bin/yaze_test --unit # Unit tests only
|
||||
./build/bin/yaze_test --integration # Integration tests
|
||||
./build/bin/yaze_test --e2e --show-gui # End-to-end GUI tests
|
||||
|
||||
# Run with ROM-dependent tests
|
||||
./build/bin/yaze_test --rom-dependent --rom-path zelda3.sfc
|
||||
|
||||
# Run specific test by name
|
||||
./build/bin/yaze_test "*Asar*"
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Core Components
|
||||
|
||||
**ROM Management** (`src/app/rom.h`, `src/app/rom.cc`)
|
||||
- Central `Rom` class manages all ROM data access
|
||||
- Provides transaction-based read/write operations
|
||||
- Handles graphics buffer, palettes, and resource labels
|
||||
- Key methods: `LoadFromFile()`, `ReadByte()`, `WriteByte()`, `ReadTransaction()`, `WriteTransaction()`
|
||||
|
||||
**Editor System** (`src/app/editor/`)
|
||||
- Base `Editor` class defines interface for all editor types
|
||||
- Major editors: `OverworldEditor`, `DungeonEditor`, `GraphicsEditor`, `PaletteEditor`
|
||||
- `EditorManager` coordinates multiple editor instances
|
||||
- Card-based UI system for dockable editor panels
|
||||
|
||||
**Graphics System** (`src/app/gfx/`)
|
||||
- `gfx::Bitmap`: Core bitmap class with SDL surface integration
|
||||
- `gfx::Arena`: Centralized singleton for progressive asset loading (priority-based texture queuing)
|
||||
- `gfx::SnesPalette` and `gfx::SnesColor`: SNES color/palette management
|
||||
- `gfx::Tile16` and `gfx::SnesTile`: Tile format representations
|
||||
- Graphics sheets (223 total) loaded from ROM with compression support (LC-LZ2)
|
||||
|
||||
**Zelda3-Specific Logic** (`src/zelda3/`)
|
||||
- `zelda3::Overworld`: Manages 160+ overworld maps (Light World, Dark World, Special World)
|
||||
- `zelda3::OverworldMap`: Individual map data (tiles, entities, properties)
|
||||
- `zelda3::Dungeon`: Dungeon room management (296 rooms)
|
||||
- `zelda3::Sprite`: Sprite and enemy data structures
|
||||
|
||||
**Canvas System** (`src/app/gui/canvas.h`)
|
||||
- `gui::Canvas`: ImGui-based drawable canvas with pan/zoom/grid support
|
||||
- Context menu system for entity editing
|
||||
- Automation API for AI agent integration
|
||||
- Usage tracker for click/interaction statistics
|
||||
|
||||
**Asar Integration** (`src/core/asar_wrapper.h`)
|
||||
- `core::AsarWrapper`: C++ wrapper around Asar assembler library
|
||||
- Provides patch application, symbol extraction, and error reporting
|
||||
- Used by CLI tool and GUI for assembly patching
|
||||
|
||||
**z3ed CLI Tool** (`src/cli/`)
|
||||
- AI-powered command-line interface with Ollama and Gemini support
|
||||
- TUI (Terminal UI) components for interactive editing
|
||||
- Resource catalog system for ROM data queries
|
||||
- Test suite generation and execution
|
||||
- Network collaboration support (experimental)
|
||||
|
||||
### Key Architectural Patterns
|
||||
|
||||
**Pattern 1: Modular Editor Design**
|
||||
- Large editor classes decomposed into smaller, single-responsibility modules
|
||||
- Separate renderer classes (e.g., `OverworldEntityRenderer`)
|
||||
- UI panels managed by dedicated classes (e.g., `MapPropertiesSystem`)
|
||||
- Main editor acts as coordinator, not implementer
|
||||
|
||||
**Pattern 2: Callback-Based Communication**
|
||||
- Child components receive callbacks from parent editors via `SetCallbacks()`
|
||||
- Avoids circular dependencies between modules
|
||||
- Example: `MapPropertiesSystem` calls `RefreshCallback` to notify `OverworldEditor`
|
||||
|
||||
**Pattern 3: Progressive Loading via `gfx::Arena`**
|
||||
- All expensive asset loading performed asynchronously
|
||||
- Queue textures with priority: `gfx::Arena::Get().QueueDeferredTexture(bitmap, priority)`
|
||||
- Process in batches during `Update()`: `GetNextDeferredTextureBatch(high_count, low_count)`
|
||||
- Prevents UI freezes during ROM loading
|
||||
|
||||
**Pattern 4: Bitmap/Surface Synchronization**
|
||||
- `Bitmap::data_` (C++ vector) and `surface_->pixels` (SDL buffer) must stay in sync
|
||||
- Use `set_data()` for bulk replacement (syncs both)
|
||||
- Use `WriteToPixel()` for single-pixel modifications
|
||||
- Never assign directly to `mutable_data()` for replacements
|
||||
|
||||
## Development Guidelines
|
||||
|
||||
### Naming Conventions
|
||||
- **Load**: Reading data from ROM into memory
|
||||
- **Render**: Processing graphics data into bitmaps/textures (CPU pixel operations)
|
||||
- **Draw**: Displaying textures/shapes on canvas via ImGui (GPU rendering)
|
||||
- **Update**: UI state changes, property updates, input handling
|
||||
|
||||
### Graphics Refresh Logic
|
||||
When a visual property changes:
|
||||
1. Update the property in the data model
|
||||
2. Call relevant `Load*()` method (e.g., `map.LoadAreaGraphics()`)
|
||||
3. Force a redraw: Use `Renderer::Get().RenderBitmap()` for immediate updates (not `UpdateBitmap()`)
|
||||
|
||||
### Graphics Sheet Management
|
||||
When modifying graphics sheets:
|
||||
1. Get mutable reference: `auto& sheet = Arena::Get().mutable_gfx_sheet(index);`
|
||||
2. Make modifications
|
||||
3. Notify Arena: `Arena::Get().NotifySheetModified(index);`
|
||||
4. Changes propagate automatically to all editors
|
||||
|
||||
### UI Theming System
|
||||
- **Never use hardcoded colors** - Always use `AgentUITheme`
|
||||
- Fetch theme: `const auto& theme = AgentUI::GetTheme();`
|
||||
- Use semantic colors: `theme.panel_bg_color`, `theme.status_success`, etc.
|
||||
- Use helper functions: `AgentUI::PushPanelStyle()`, `AgentUI::RenderSectionHeader()`, `AgentUI::StyledButton()`
|
||||
|
||||
### Multi-Area Map Configuration
|
||||
- **Always use** `zelda3::Overworld::ConfigureMultiAreaMap()` when changing map area size
|
||||
- Never set `area_size` property directly
|
||||
- Method handles parent ID assignment and ROM data persistence
|
||||
|
||||
### Version-Specific Features
|
||||
- Check ROM's `asm_version` byte before showing UI for ZSCustomOverworld features
|
||||
- Display helpful messages for unsupported features (e.g., "Requires ZSCustomOverworld v3+")
|
||||
|
||||
### Entity Visibility Standards
|
||||
Render overworld entities with high-contrast colors at 0.85f alpha:
|
||||
- **Entrances**: Bright yellow-gold
|
||||
- **Exits**: Cyan-white
|
||||
- **Items**: Bright red
|
||||
- **Sprites**: Bright magenta
|
||||
|
||||
### Debugging with Startup Flags
|
||||
Jump directly to editors for faster development:
|
||||
```bash
|
||||
# Open specific editor with ROM
|
||||
./yaze --rom_file=zelda3.sfc --editor=Dungeon
|
||||
|
||||
# Open with specific cards visible
|
||||
./yaze --rom_file=zelda3.sfc --editor=Dungeon --cards="Room 0,Room 1,Object Editor"
|
||||
|
||||
# Enable debug logging
|
||||
./yaze --debug --log_file=debug.log --rom_file=zelda3.sfc --editor=Overworld
|
||||
```
|
||||
|
||||
Available editors: Assembly, Dungeon, Graphics, Music, Overworld, Palette, Screen, Sprite, Message, Hex, Agent, Settings
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Test Organization
|
||||
```
|
||||
test/
|
||||
├── unit/ # Fast, isolated component tests (no ROM required)
|
||||
├── integration/ # Multi-component tests (may require ROM)
|
||||
├── e2e/ # Full UI workflow tests (ImGui Test Engine)
|
||||
├── benchmarks/ # Performance tests
|
||||
└── mocks/ # Mock objects for isolation
|
||||
```
|
||||
|
||||
### Test Categories
|
||||
- **Unit Tests**: Fast, self-contained, no external dependencies (primary CI validation)
|
||||
- **Integration Tests**: Test component interactions, may require ROM files
|
||||
- **E2E Tests**: Full user workflows driven by ImGui Test Engine (requires GUI)
|
||||
- **ROM-Dependent Tests**: Any test requiring an actual Zelda3 ROM file
|
||||
|
||||
### Writing New Tests
|
||||
- New class `MyClass`? → Add `test/unit/my_class_test.cc`
|
||||
- Testing with ROM? → Add `test/integration/my_class_rom_test.cc`
|
||||
- Testing UI workflow? → Add `test/e2e/my_class_workflow_test.cc`
|
||||
|
||||
### GUI Test Automation
|
||||
- E2E framework uses `ImGuiTestEngine` for UI automation
|
||||
- All major widgets have stable IDs for discovery
|
||||
- Test helpers in `test/test_utils.h`: `LoadRomInTest()`, `OpenEditorInTest()`
|
||||
- AI agents can use `z3ed gui discover`, `z3ed gui click` for automation
|
||||
|
||||
## Platform-Specific Notes
|
||||
|
||||
### Windows
|
||||
- Requires Visual Studio 2022 with "Desktop development with C++" workload
|
||||
- Run `scripts\verify-build-environment.ps1` before building
|
||||
- gRPC builds take 15-20 minutes first time (use vcpkg for faster builds)
|
||||
- Watch for path length limits: Enable long paths with `git config --global core.longpaths true`
|
||||
|
||||
### macOS
|
||||
- Supports both Apple Silicon (ARM64) and Intel (x86_64)
|
||||
- Use `mac-uni` preset for universal binaries
|
||||
- Bundled Abseil used by default to avoid deployment target mismatches
|
||||
- **ARM64 Note**: gRPC v1.67.1 is the tested stable version (see BUILD-TROUBLESHOOTING.md for details)
|
||||
|
||||
### Linux
|
||||
- Requires GCC 13+ or Clang 16+
|
||||
- Install dependencies: `libgtk-3-dev`, `libdbus-1-dev`, `pkg-config`
|
||||
|
||||
**Platform-specific build issues?** See `docs/BUILD-TROUBLESHOOTING.md`
|
||||
|
||||
## CI/CD Pipeline
|
||||
|
||||
The project uses GitHub Actions for continuous integration and deployment:
|
||||
|
||||
### Workflows
|
||||
- **ci.yml**: Build and test on Linux, macOS, Windows (runs on push to master/develop, PRs)
|
||||
- **release.yml**: Build release artifacts and publish GitHub releases
|
||||
- **code-quality.yml**: clang-format, cppcheck, clang-tidy checks
|
||||
- **security.yml**: Security scanning and dependency audits
|
||||
|
||||
### Composite Actions
|
||||
Reusable build steps in `.github/actions/`:
|
||||
- `setup-build` - Configure build environment with caching
|
||||
- `build-project` - Build with CMake and optimal settings
|
||||
- `run-tests` - Execute test suites with result uploads
|
||||
|
||||
### Key Features
|
||||
- CPM dependency caching for faster builds
|
||||
- sccache/ccache for incremental compilation
|
||||
- Platform-specific test execution (stable, unit, integration)
|
||||
- Automatic artifact uploads on build/test failures
|
||||
|
||||
## Git Workflow
|
||||
|
||||
**Current Phase:** Pre-1.0 (Relaxed Rules)
|
||||
|
||||
For detailed workflow documentation, see `docs/B4-git-workflow.md`.
|
||||
|
||||
### Quick Guidelines
|
||||
- **Documentation/Small fixes**: Commit directly to `master` or `develop`
|
||||
- **Experiments/Features**: Use feature branches (`feature/<description>`)
|
||||
- **Breaking changes**: Use feature branches and document in changelog
|
||||
- **Commit messages**: Follow Conventional Commits (`feat:`, `fix:`, `docs:`, etc.)
|
||||
|
||||
### Planned Workflow (Post-1.0)
|
||||
When the project reaches v1.0 or has multiple active contributors, we'll transition to formal Git Flow with protected branches, required PR reviews, and release branches.
|
||||
|
||||
## Code Style
|
||||
|
||||
- Format code with clang-format: `cmake --build build --target format`
|
||||
- Check format without changes: `cmake --build build --target format-check`
|
||||
- Style guide: Google C++ Style Guide (enforced via clang-format)
|
||||
- Use `absl::Status` and `absl::StatusOr<T>` for error handling
|
||||
- Macros: `RETURN_IF_ERROR()`, `ASSIGN_OR_RETURN()` for status propagation
|
||||
|
||||
## Important File Locations
|
||||
|
||||
- ROM loading: `src/app/rom.cc:Rom::LoadFromFile()`
|
||||
- Overworld editor: `src/app/editor/overworld/overworld_editor.cc`
|
||||
- Dungeon editor: `src/app/editor/dungeon/dungeon_editor.cc`
|
||||
- Graphics arena: `src/app/gfx/snes_tile.cc` and `src/app/gfx/bitmap.cc`
|
||||
- Asar wrapper: `src/core/asar_wrapper.cc`
|
||||
- Main application: `src/yaze.cc`
|
||||
- CLI tool: `src/cli/z3ed.cc`
|
||||
- Test runner: `test/yaze_test.cc`
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
1. **Bitmap data desync**: Always use `set_data()` for bulk updates, not `mutable_data()` assignment
|
||||
2. **Missing texture queue processing**: Call `ProcessTextureQueue()` every frame
|
||||
3. **Incorrect graphics refresh order**: Update model → Load from ROM → Force render
|
||||
4. **Skipping `ConfigureMultiAreaMap()`**: Always use this method for map size changes
|
||||
5. **Hardcoded colors**: Use `AgentUITheme` system, never raw `ImVec4` values
|
||||
6. **Blocking texture loads**: Use `gfx::Arena` deferred loading system
|
||||
7. **Missing ROM state checks**: Always verify `rom_->is_loaded()` before operations
|
||||
62
CONTRIBUTING.md
Normal file
62
CONTRIBUTING.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Contributing to YAZE
|
||||
|
||||
The YAZE project reserves **master** for promoted releases and uses **develop**
|
||||
for day‑to‑day work. Larger efforts should branch from `develop` and rebase
|
||||
frequently. Follow the existing Conventional Commit subject format when pushing
|
||||
history (e.g. `feat: add sprite tab filtering`, `fix: guard null rom path`).
|
||||
|
||||
The repository ships a clang-format and clang-tidy configuration (Google style,
|
||||
2-space indentation, 80-column wrap). Always run formatter and address
|
||||
clang-tidy warnings on the files you touch.
|
||||
|
||||
## Engineering Expectations
|
||||
|
||||
1. **Refactor deliberately**
|
||||
- Break work into reviewable patches.
|
||||
- Preserve behaviour while moving code; add tests before/after when possible.
|
||||
- Avoid speculative abstractions—prove value in the PR description.
|
||||
- When deleting or replacing major systems, document the migration (see
|
||||
`handbook/blueprints/editor-manager-architecture.md` for precedent).
|
||||
|
||||
2. **Verify changes**
|
||||
- Use the appropriate CMake preset for your platform (`mac-dbg`, `lin-dbg`,
|
||||
`win-dbg`, etc.).
|
||||
- Run the targeted test slice: `ctest --preset dev` for fast coverage; add new
|
||||
GoogleTest cases where feasible.
|
||||
- For emulator-facing work, exercise relevant UI flows manually before
|
||||
submitting.
|
||||
- Explicitly call out remaining manual-verification items in the PR.
|
||||
|
||||
3. **Work with the build & CI**
|
||||
- Honour the existing `cmake --preset` structure; avoid hardcoding paths.
|
||||
- Keep `vcpkg.json` and the CI workflows in sync when adding dependencies.
|
||||
- Use the deferred texture queue and arena abstractions rather than talking to
|
||||
SDL directly.
|
||||
|
||||
## Documentation Style
|
||||
|
||||
YAZE documentation is concise and factual. When updating `docs/public/`:
|
||||
|
||||
- Avoid marketing language, emojis, or decorative status badges.
|
||||
- Record the actual project state (e.g., mark editors as **stable** vs
|
||||
**experimental** based on current source).
|
||||
- Provide concrete references (file paths, function names) when describing
|
||||
behaviour.
|
||||
- Prefer bullet lists and short paragraphs; keep quick-start examples runnable.
|
||||
- Update cross-references when moving or renaming files.
|
||||
- For review handoffs, capture what remains to be done instead of transfusing raw
|
||||
planning logs.
|
||||
|
||||
If you notice obsolete or inaccurate docs, fix them in the same change rather
|
||||
than layering new “note” files.
|
||||
|
||||
## Pull Request Checklist
|
||||
|
||||
- [ ] Tests and builds succeed on your platform (note the preset/command used).
|
||||
- [ ] New code is formatted (`clang-format`) and clean (`clang-tidy`).
|
||||
- [ ] Documentation and comments reflect current behaviour.
|
||||
- [ ] Breaking changes are mentioned in the PR and, if relevant, `docs/public/reference/changelog.md`.
|
||||
- [ ] Any new assets or scripts are referenced in the repo’s structure guides.
|
||||
|
||||
Respect these guidelines and we can keep the codebase approachable, accurate,
|
||||
and ready for the next set of contributors.
|
||||
215
GEMINI.md
Normal file
215
GEMINI.md
Normal file
@@ -0,0 +1,215 @@
|
||||
# Gemini Workflow Instructions for the `yaze` Project
|
||||
|
||||
This document provides a summary of the `yaze` project to guide an AI assistant in understanding the codebase, architecture, and development workflows.
|
||||
|
||||
> **Coordination Requirement**
|
||||
> Gemini-based agents must read and update the shared coordination board
|
||||
> (`docs/internal/agents/coordination-board.md`) before making changes. Follow the protocol in
|
||||
> `AGENTS.md`, use the appropriate persona ID (e.g., `GEMINI_AUTOM`), and respond to any pending
|
||||
> entries targeting you.
|
||||
|
||||
## User Profile
|
||||
|
||||
- **User**: A Google programmer working on ROM hacking projects on macOS.
|
||||
- **IDE**: Visual Studio Code with the CMake Tools extension.
|
||||
- **Build System**: CMake with a preference for the "Unix Makefiles" generator.
|
||||
- **Workflow**: Uses CMake presets and a separate `build_test` directory for test builds.
|
||||
- **AI Assistant Build Policy**: When the AI assistant needs to build the project, it must use a dedicated build directory (e.g., `build_ai` or `build_agent`) to avoid interrupting the user's active builds. Never use `build` or `build_test` directories.
|
||||
|
||||
## Project Overview
|
||||
|
||||
- **`yaze`**: A cross-platform GUI editor for "The Legend of Zelda: A Link to the Past" (ALTTP) ROMs. It is designed for compatibility with ZScream projects.
|
||||
- **`z3ed`**: A powerful command-line interface (CLI) for `yaze`. It features a resource-oriented design (`z3ed <resource> <action>`) and serves as the primary API for an AI-driven conversational agent.
|
||||
- **`yaze.org`**: The file `docs/yaze.org` is an Emacs Org-Mode file used as a development tracker for active issues and features.
|
||||
|
||||
## Build Instructions
|
||||
|
||||
- Use the presets in `CMakePresets.json` (debug, AI, release, dev, CI, etc.). Always run the verifier
|
||||
script before the first build on a machine.
|
||||
- Gemini agents must configure/build in dedicated directories (`build_ai`, `build_agent`, …) to avoid
|
||||
touching the user’s `build` or `build_test` folders.
|
||||
- Consult [`docs/public/build/quick-reference.md`](docs/public/build/quick-reference.md) for the
|
||||
canonical command list, preset overview, and testing guidance.
|
||||
|
||||
## Testing
|
||||
|
||||
- **Framework**: GoogleTest.
|
||||
- **Test Categories**:
|
||||
- `STABLE`: Fast, reliable, run in CI.
|
||||
- `ROM_DEPENDENT`: Require a ROM file, skipped in CI unless a ROM is provided.
|
||||
- `EXPERIMENTAL`: May be unstable, allowed to fail.
|
||||
- **Running Tests**:
|
||||
```bash
|
||||
# Run stable tests using ctest and presets
|
||||
ctest --preset dev
|
||||
|
||||
# Run comprehensive overworld tests (requires a ROM)
|
||||
./scripts/run_overworld_tests.sh /path/to/zelda3.sfc
|
||||
```
|
||||
- **E2E GUI Testing**: The project includes a sophisticated end-to-end testing framework using `ImGuiTestEngine`, accessible via a gRPC service. The `z3ed agent test` command can execute natural language prompts as GUI tests.
|
||||
|
||||
## Core Architecture & Features
|
||||
|
||||
- **Overworld Editor**: Full support for vanilla and `ZSCustomOverworld` v2/v3 ROMs, ensuring compatibility with ZScream projects.
|
||||
- **Dungeon Editor**: A modular, component-based system for editing rooms, objects, sprites, and more. See `docs/E2-dungeon-editor-guide.md` and `docs/E3-dungeon-editor-design.md`.
|
||||
- **Graphics System**: A performant system featuring:
|
||||
- `Arena`-based resource management.
|
||||
- `Bitmap` class for SNES-specific graphics formats.
|
||||
- `Tilemap` with an LRU cache.
|
||||
- `AtlasRenderer` for batched drawing.
|
||||
- **Asar Integration**: Built-in support for the Asar 65816 assembler to apply assembly patches to the ROM.
|
||||
|
||||
## Editor System Architecture
|
||||
|
||||
The editor system is designed around a central `EditorManager` that orchestrates multiple editors and UI components.
|
||||
|
||||
- **`EditorManager`**: The top-level class that manages multiple `RomSession`s, the main menu, and all editor windows. It handles the application's main update loop.
|
||||
- **`RomSession`**: Each session encapsulates a `Rom` instance and a corresponding `EditorSet`, allowing multiple ROMs to be open simultaneously.
|
||||
- **`EditorSet`**: A container for all individual editor instances (Overworld, Dungeon, etc.) associated with a single ROM session.
|
||||
- **`Editor` (Base Class)**: A virtual base class (`src/app/editor/editor.h`) that defines a common interface for all editors, including methods like `Initialize`, `Load`, `Update`, and `Save`.
|
||||
|
||||
### Component-Based Editors
|
||||
The project is moving towards a component-based architecture to improve modularity and maintainability. This is most evident in the Dungeon Editor.
|
||||
|
||||
- **Dungeon Editor**: Refactored into a collection of single-responsibility components orchestrated by `DungeonEditor`:
|
||||
- `DungeonRoomSelector`: Manages the UI for selecting rooms and entrances.
|
||||
- `DungeonCanvasViewer`: Handles the rendering of the dungeon room on the main canvas.
|
||||
- `DungeonObjectSelector`: Provides the UI for browsing and selecting objects, sprites, and other editable elements.
|
||||
- `DungeonObjectInteraction`: Manages mouse input, selection, and drag-and-drop on the canvas.
|
||||
- `DungeonToolset`: The main toolbar for the editor.
|
||||
- `DungeonRenderer`: A dedicated rendering engine for dungeon objects, featuring a cache for performance.
|
||||
- `DungeonRoomLoader`: Handles the logic for loading all room data from the ROM, now optimized with parallel processing.
|
||||
- `DungeonUsageTracker`: Analyzes and displays statistics on resource usage (blocksets, palettes, etc.).
|
||||
|
||||
- **Overworld Editor**: Also employs a component-based approach with helpers like `OverworldEditorManager` for ZSCustomOverworld v3 features and `MapPropertiesSystem` for UI panels.
|
||||
|
||||
### Specialized Editors
|
||||
- **Code Editors**: `AssemblyEditor` (a full-featured text editor) and `MemoryEditor` (a hex viewer).
|
||||
- **Graphics Editors**: `GraphicsEditor`, `PaletteEditor`, `GfxGroupEditor`, `ScreenEditor`, and the highly detailed `Tile16Editor` provide tools for all visual assets.
|
||||
- **Content Editors**: `SpriteEditor`, `MessageEditor`, and `MusicEditor` manage specific game content.
|
||||
|
||||
### System Components
|
||||
Located in `src/app/editor/system/`, these components provide the core application framework:
|
||||
- `SettingsEditor`: Manages global and project-specific feature flags.
|
||||
- `PopupManager`, `ToastManager`: Handle all UI dialogs and notifications.
|
||||
- `ShortcutManager`, `CommandManager`: Manage keyboard shortcuts and command palette functionality.
|
||||
- `ProposalDrawer`, `AgentChatWidget`: Key UI components for the AI Agent Workflow, allowing for proposal review and conversational interaction.
|
||||
|
||||
## Game Data Models (`zelda3` Namespace)
|
||||
|
||||
The logic and data structures for ALTTP are primarily located in `src/zelda3/`.
|
||||
|
||||
- **`Rom` Class (`app/rom.h`)**: This is the most critical data class. It holds the entire ROM content in a `std::vector<uint8_t>` and provides the central API for all data access.
|
||||
- **Responsibilities**: Handles loading/saving ROM files, stripping SMC headers, and providing low-level read/write primitives (e.g., `ReadByte`, `WriteWord`).
|
||||
- **Game-Specific Loading**: The `LoadZelda3` method populates game-specific data structures like palettes (`palette_groups_`) and graphics groups.
|
||||
- **State**: Manages a `dirty_` flag to track unsaved changes.
|
||||
|
||||
- **Overworld Model (`zelda3/overworld/`)**:
|
||||
- `Overworld`: The main container class that orchestrates the loading of all overworld data, including maps, tiles, and entities. It correctly handles logic for both vanilla and `ZSCustomOverworld` ROMs.
|
||||
- `OverworldMap`: Represents a single overworld screen, loading its own properties (palettes, graphics, music) based on the ROM version.
|
||||
- `GameEntity`: A base class in `zelda3/common.h` for all interactive overworld elements like `OverworldEntrance`, `OverworldExit`, `OverworldItem`, and `Sprite`.
|
||||
|
||||
- **Dungeon Model (`zelda3/dungeon/`)**:
|
||||
- `DungeonEditorSystem`: A high-level API that serves as the backend for the UI, managing all dungeon editing logic (adding/removing sprites, items, doors, etc.).
|
||||
- `Room`: Represents a single dungeon room, containing its objects, sprites, layout, and header information.
|
||||
- `RoomObject` & `RoomLayout`: Define the structural elements of a room.
|
||||
- `ObjectParser` & `ObjectRenderer`: High-performance components for directly parsing object data from the ROM and rendering them, avoiding the need for full SNES emulation.
|
||||
|
||||
- **Sprite Model (`zelda3/sprite/`)**:
|
||||
- `Sprite`: Represents an individual sprite (enemy, NPC).
|
||||
- `SpriteBuilder`: A fluent API for programmatically constructing custom sprites.
|
||||
- `zsprite.h`: Data structures for compatibility with Zarby's ZSpriteMaker format.
|
||||
|
||||
- **Other Data Models**:
|
||||
- `MessageData` (`message/`): Handles the game's text and dialogue system.
|
||||
- `Inventory`, `TitleScreen`, `DungeonMap` (`screen/`): Represent specific non-gameplay screens.
|
||||
- `music::Tracker` (`music/`): Contains legacy code from Hyrule Magic for handling SNES music data.
|
||||
|
||||
## Graphics System (`gfx` Namespace)
|
||||
|
||||
The `gfx` namespace contains a highly optimized graphics engine tailored for SNES ROM hacking.
|
||||
|
||||
- **Core Concepts**:
|
||||
- **`Bitmap`**: The fundamental class for image data. It supports SNES pixel formats, palette management, and is optimized with features like dirty-region tracking and a hash-map-based palette lookup cache for O(1) performance.
|
||||
- **SNES Formats**: `snes_color`, `snes_palette`, and `snes_tile` provide structures and conversion functions for handling SNES-specific data (15-bit color, 4BPP/8BPP tiles, etc.).
|
||||
- **`Tilemap`**: Represents a collection of tiles, using a texture `atlas` and a `TileCache` (with LRU eviction) for efficient rendering.
|
||||
|
||||
- **Resource Management & Performance**:
|
||||
- **`Arena`**: A singleton that manages all graphics resources. It pools `SDL_Texture` and `SDL_Surface` objects to reduce allocation overhead and uses custom deleters for automatic cleanup. It also manages the 223 global graphics sheets for the game.
|
||||
- **`MemoryPool`**: A low-level, high-performance memory allocator that provides pre-allocated blocks for common graphics sizes, reducing `malloc` overhead and memory fragmentation.
|
||||
- **`AtlasRenderer`**: A key performance component that batches draw calls by combining multiple smaller graphics onto a single large texture atlas.
|
||||
- **Batching**: The `Arena` supports batching texture updates via `QueueTextureUpdate`, which minimizes expensive, blocking calls to the SDL rendering API.
|
||||
|
||||
- **Format Handling & Optimization**:
|
||||
- **`compression.h`**: Contains SNES-specific compression algorithms (LC-LZ2, Hyrule Magic) for handling graphics data from the ROM.
|
||||
- **`BppFormatManager`**: A system for analyzing and converting between different bits-per-pixel (BPP) formats.
|
||||
- **`GraphicsOptimizer`**: A high-level tool that uses the `BppFormatManager` to analyze graphics sheets and recommend memory and performance optimizations.
|
||||
- **`scad_format.h`**: Provides compatibility with legacy Nintendo CAD file formats (CGX, SCR, COL) from the "gigaleak".
|
||||
|
||||
- **Performance Monitoring**:
|
||||
- **`PerformanceProfiler`**: A comprehensive system for timing operations using a `ScopedTimer` RAII class.
|
||||
- **`PerformanceDashboard`**: An ImGui-based UI for visualizing real-time performance metrics collected by the profiler.
|
||||
|
||||
## GUI System (`gui` Namespace)
|
||||
|
||||
The `yaze` user interface is built with **ImGui** and is located in `src/app/gui`. It features a modern, component-based architecture designed for modularity, performance, and testability.
|
||||
|
||||
### Canvas System (`gui::Canvas`)
|
||||
The canvas is the core of all visual editors. The main `Canvas` class (`src/app/gui/canvas.h`) has been refactored from a monolithic class into a coordinator that leverages a set of single-responsibility components found in `src/app/gui/canvas/`.
|
||||
|
||||
- **`Canvas`**: The main canvas widget. It provides a modern, ImGui-style interface (`Begin`/`End`) and coordinates the various sub-components for drawing, interaction, and configuration.
|
||||
- **`CanvasInteractionHandler`**: Manages all direct user input on the canvas, such as mouse clicks, drags, and selections for tile painting and object manipulation.
|
||||
- **`CanvasContextMenu`**: A powerful, data-driven context menu system. It is aware of the current `CanvasUsage` mode (e.g., `TilePainting`, `PaletteEditing`) and displays relevant menu items dynamically.
|
||||
- **`CanvasModals`**: Handles all modal dialogs related to the canvas, such as "Advanced Properties," "Scaling Controls," and "BPP Conversion," ensuring a consistent UX.
|
||||
- **`CanvasUsageTracker` & `CanvasPerformanceIntegration`**: These components provide deep analytics and performance monitoring. They track user interactions, operation timings, and memory usage, integrating with the global `PerformanceDashboard` to identify bottlenecks.
|
||||
- **`CanvasUtils`**: A collection of stateless helper functions for common canvas tasks like grid drawing, coordinate alignment, and size calculations, promoting code reuse.
|
||||
|
||||
### Theming and Styling
|
||||
The visual appearance of the editor is highly customizable through a robust theming system.
|
||||
|
||||
- **`ThemeManager`**: A singleton that manages `EnhancedTheme` objects. It can load custom themes from `.theme` files, allowing users to personalize the editor's look and feel. It includes a built-in theme editor and selector UI.
|
||||
- **`BackgroundRenderer`**: Renders the animated, futuristic grid background for the main docking space, providing a polished, modern aesthetic.
|
||||
- **`style.cc` & `color.cc`**: Contain custom ImGui styling functions (`ColorsYaze`), `SnesColor` conversion utilities, and other helpers to maintain a consistent visual identity.
|
||||
|
||||
### Specialized UI Components
|
||||
The `gui` namespace includes several powerful, self-contained widgets for specific ROM hacking tasks.
|
||||
|
||||
- **`BppFormatUI`**: A comprehensive UI for managing SNES bits-per-pixel (BPP) graphics formats. It provides a format selector, a detailed analysis panel, a side-by-side conversion preview, and a batch comparison tool.
|
||||
- **`EnhancedPaletteEditor`**: An advanced tool for editing `SnesPalette` objects. It features a grid-based editor, a ROM palette manager for loading palettes directly from the game, and a color analysis view to inspect pixel distribution.
|
||||
- **`TextEditor`**: A full-featured text editor widget with syntax highlighting for 65816 assembly, undo/redo functionality, and standard text manipulation features.
|
||||
- **`AssetBrowser`**: A flexible, icon-based browser for viewing and managing game assets, such as graphics sheets.
|
||||
|
||||
### Widget Registry for Automation
|
||||
A key feature for test automation and AI agent integration is the discoverability of UI elements.
|
||||
|
||||
- **`WidgetIdRegistry`**: A singleton that catalogs all registered GUI widgets. It assigns a stable, hierarchical path (e.g., `Overworld/Canvas/Map`) to each widget, making the UI programmatically discoverable. This is the backbone of the `z3ed agent test` command.
|
||||
- **`WidgetIdScope`**: An RAII helper that simplifies the creation of hierarchical widget IDs by managing an ID stack, ensuring that widget paths are consistent and predictable.
|
||||
|
||||
## ROM Hacking Context
|
||||
|
||||
- **Game**: The Legend of Zelda: A Link to the Past (US/JP).
|
||||
- **`ZSCustomOverworld`**: A popular system for expanding overworld editing capabilities. `yaze` is designed to be fully compatible with ZScream's implementation of v2 and v3.
|
||||
- **Assembly**: Uses `asar` for 65816 assembly. A style guide is available at `docs/E1-asm-style-guide.md`.
|
||||
- **`usdasm` Disassembly**: The user has a local copy of the `usdasm` ALTTP disassembly at `/Users/scawful/Code/usdasm` which can be used for reference.
|
||||
|
||||
## Git Workflow
|
||||
|
||||
The project follows a simplified Git workflow for pre-1.0 development, with a more formal process documented for the future. For details, see `docs/B4-git-workflow.md`.
|
||||
|
||||
- **Current (Pre-1.0)**: A relaxed model is in use. Direct commits to `develop` or `master` are acceptable for documentation and small fixes. Feature branches are used for larger, potentially breaking changes.
|
||||
- **Future (Post-1.0)**: The project will adopt a formal Git Flow model with `master`, `develop`, feature, release, and hotfix branches.
|
||||
|
||||
## AI Agent Workflow (`z3ed agent`)
|
||||
|
||||
A primary focus of the `yaze` project is its AI-driven agentic workflow, orchestrated by the `z3ed` CLI.
|
||||
|
||||
- **Vision**: To create a conversational ROM hacking assistant that can inspect the ROM and perform edits based on natural language.
|
||||
- **Core Loop (MCP)**:
|
||||
1. **Model (Plan)**: The user provides a prompt. The agent uses an LLM (Ollama or Gemini) to create a plan, which is a sequence of `z3ed` commands.
|
||||
2. **Code (Generate)**: The LLM generates the commands based on a machine-readable catalog of the CLI's capabilities.
|
||||
3. **Program (Execute)**: The `z3ed` agent executes the commands.
|
||||
- **Proposal System**: To ensure safety, agent-driven changes are not applied directly. They are executed in a **sandboxed ROM copy** and saved as a **proposal**.
|
||||
- **Review & Acceptance**: The user can review the proposed changes via `z3ed agent diff` or a dedicated `ProposalDrawer` in the `yaze` GUI. The user must explicitly **accept** a proposal to merge the changes into the main ROM.
|
||||
- **Tool Use**: The agent can use read-only `z3ed` commands (e.g., `overworld-find-tile`, `dungeon-list-sprites`) as "tools" to inspect the ROM and gather context to answer questions or formulate a plan.
|
||||
- **API Discovery**: The agent learns the available commands and their schemas by calling `z3ed agent describe`, which exports the entire CLI surface area in a machine-readable format.
|
||||
- **Function Schemas**: The Gemini AI service uses function calling schemas defined in `assets/agent/function_schemas.json`. These schemas are automatically copied to the build directory and loaded at runtime. To modify the available functions, edit this JSON file rather than hardcoding them in the C++ source.
|
||||
BIN
assets/zelda3.sfc
Normal file
BIN
assets/zelda3.sfc
Normal file
Binary file not shown.
289
docs/internal/AI_API_ENHANCEMENT_HANDOFF.md
Normal file
289
docs/internal/AI_API_ENHANCEMENT_HANDOFF.md
Normal file
@@ -0,0 +1,289 @@
|
||||
# AI API & Agentic Workflow Enhancement - Handoff Document
|
||||
|
||||
**Date**: 2025-01-XX
|
||||
**Status**: Phase 1 Complete, Phase 2-4 Pending
|
||||
**Branch**: (to be determined)
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This document tracks progress on transforming Yaze into an AI-native platform with unified model management, API interface, and enhanced agentic workflows. Phase 1 (Unified Model Management) is complete. Phases 2-4 require implementation.
|
||||
|
||||
## Completed Work (Phase 1)
|
||||
|
||||
### 1. Unified AI Model Management ✅
|
||||
|
||||
#### Core Infrastructure
|
||||
- **`ModelInfo` struct** (`src/cli/service/ai/common.h`)
|
||||
- Standardized model representation across all providers
|
||||
- Fields: `name`, `display_name`, `provider`, `description`, `family`, `parameter_size`, `quantization`, `size_bytes`, `is_local`
|
||||
|
||||
- **`ModelRegistry` class** (`src/cli/service/ai/model_registry.h/.cc`)
|
||||
- Singleton pattern for managing multiple `AIService` instances
|
||||
- `RegisterService()` - Add service instances
|
||||
- `ListAllModels()` - Aggregate models from all registered services
|
||||
- Thread-safe with mutex protection
|
||||
|
||||
#### AIService Interface Updates
|
||||
- **`AIService::ListAvailableModels()`** - Virtual method returning `std::vector<ModelInfo>`
|
||||
- **`AIService::GetProviderName()`** - Virtual method returning provider identifier
|
||||
- Default implementations provided in base class
|
||||
|
||||
#### Provider Implementations
|
||||
- **`OllamaAIService::ListAvailableModels()`**
|
||||
- Queries `/api/tags` endpoint
|
||||
- Maps Ollama's model structure to `ModelInfo`
|
||||
- Handles size, quantization, family metadata
|
||||
|
||||
- **`GeminiAIService::ListAvailableModels()`**
|
||||
- Queries Gemini API `/v1beta/models` endpoint
|
||||
- Falls back to known defaults if API key missing
|
||||
- Filters for `gemini*` models
|
||||
|
||||
#### UI Integration
|
||||
- **`AgentChatWidget::RefreshModels()`**
|
||||
- Registers Ollama and Gemini services with `ModelRegistry`
|
||||
- Aggregates models from all providers
|
||||
- Caches results in `model_info_cache_`
|
||||
|
||||
- **Header updates** (`agent_chat_widget.h`)
|
||||
- Replaced `ollama_model_info_cache_` with unified `model_info_cache_`
|
||||
- Replaced `ollama_model_cache_` with `model_name_cache_`
|
||||
- Replaced `ollama_models_loading_` with `models_loading_`
|
||||
|
||||
### Files Modified
|
||||
- `src/cli/service/ai/common.h` - Added `ModelInfo` struct
|
||||
- `src/cli/service/ai/ai_service.h` - Added `ListAvailableModels()` and `GetProviderName()`
|
||||
- `src/cli/service/ai/ollama_ai_service.h/.cc` - Implemented model listing
|
||||
- `src/cli/service/ai/gemini_ai_service.h/.cc` - Implemented model listing
|
||||
- `src/cli/service/ai/model_registry.h/.cc` - New registry class
|
||||
- `src/app/editor/agent/agent_chat_widget.h/.cc` - Updated to use registry
|
||||
|
||||
## In Progress
|
||||
|
||||
### UI Rendering Updates (Partial)
|
||||
The `RenderModelConfigControls()` function in `agent_chat_widget.cc` still references old Ollama-specific code. It needs to be updated to:
|
||||
- Use unified `model_info_cache_` instead of `ollama_model_info_cache_`
|
||||
- Display models from all providers in a single list
|
||||
- Filter by provider when a specific provider is selected
|
||||
- Show provider badges/indicators for each model
|
||||
|
||||
**Location**: `src/app/editor/agent/agent_chat_widget.cc:2083-2318`
|
||||
|
||||
**Current State**: Function still has provider-specific branches that should be unified.
|
||||
|
||||
## Remaining Work
|
||||
|
||||
### Phase 2: API Interface & Headless Mode
|
||||
|
||||
#### 2.1 HTTP Server Implementation
|
||||
**Goal**: Expose Yaze functionality via REST API for external agents
|
||||
|
||||
**Tasks**:
|
||||
1. Create `HttpServer` class in `src/cli/service/api/`
|
||||
- Use `httplib` (already in tree)
|
||||
- Start on configurable port (default 8080)
|
||||
- Handle CORS if needed
|
||||
|
||||
2. Implement endpoints:
|
||||
- `GET /api/v1/models` - List all available models (delegate to `ModelRegistry`)
|
||||
- `POST /api/v1/chat` - Send prompt to agent
|
||||
- Request: `{ "prompt": "...", "provider": "ollama", "model": "...", "history": [...] }`
|
||||
- Response: `{ "text_response": "...", "tool_calls": [...], "commands": [...] }`
|
||||
- `POST /api/v1/tool/{tool_name}` - Execute specific tool
|
||||
- Request: `{ "args": {...} }`
|
||||
- Response: `{ "result": "...", "status": "ok|error" }`
|
||||
- `GET /api/v1/health` - Health check
|
||||
- `GET /api/v1/rom/status` - ROM loading status
|
||||
|
||||
3. Integration points:
|
||||
- Initialize server in `yaze.cc` main() or via CLI flag
|
||||
- Share `Rom*` context with API handlers
|
||||
- Use `ConversationalAgentService` for chat endpoint
|
||||
- Use `ToolDispatcher` for tool endpoint
|
||||
|
||||
**Files to Create**:
|
||||
- `src/cli/service/api/http_server.h`
|
||||
- `src/cli/service/api/http_server.cc`
|
||||
- `src/cli/service/api/api_handlers.h`
|
||||
- `src/cli/service/api/api_handlers.cc`
|
||||
|
||||
**Dependencies**: `httplib`, `nlohmann/json` (already available)
|
||||
|
||||
### Phase 3: Enhanced Agentic Workflows
|
||||
|
||||
#### 3.1 Tool Expansion
|
||||
|
||||
**FileSystemTool** (`src/cli/handlers/tools/filesystem_commands.h/.cc`)
|
||||
- **Purpose**: Allow agent to read/write files outside ROM (e.g., `src/` directory)
|
||||
- **Safety**: Require user confirmation or explicit scope configuration
|
||||
- **Commands**:
|
||||
- `filesystem-read <path>` - Read file contents
|
||||
- `filesystem-write <path> <content>` - Write file (with confirmation)
|
||||
- `filesystem-list <directory>` - List directory contents
|
||||
- `filesystem-search <pattern>` - Search for files matching pattern
|
||||
|
||||
**BuildTool** (`src/cli/handlers/tools/build_commands.h/.cc`)
|
||||
- **Purpose**: Trigger builds from within agent
|
||||
- **Commands**:
|
||||
- `build-cmake <build_dir>` - Run cmake configuration
|
||||
- `build-ninja <build_dir>` - Run ninja build
|
||||
- `build-status` - Check build status
|
||||
- `build-errors` - Parse and return compilation errors
|
||||
|
||||
**Integration**:
|
||||
- Add to `ToolDispatcher::ToolCallType` enum
|
||||
- Register in `ToolDispatcher::CreateHandler()`
|
||||
- Add to `ToolDispatcher::ToolPreferences` struct
|
||||
- Update UI toggles in `AgentChatWidget::RenderToolingControls()`
|
||||
|
||||
#### 3.2 Editor State Context
|
||||
**Goal**: Feed editor state (open files, compilation errors) into agent context
|
||||
|
||||
**Tasks**:
|
||||
1. Create `EditorState` struct capturing:
|
||||
- Open file paths
|
||||
- Active editor type
|
||||
- Compilation errors (if any)
|
||||
- Recent changes
|
||||
|
||||
2. Inject into agent prompts:
|
||||
- Add to `PromptBuilder::BuildPromptFromHistory()`
|
||||
- Include in system prompt when editor state changes
|
||||
|
||||
3. Update `ConversationalAgentService`:
|
||||
- Add `SetEditorState(EditorState*)` method
|
||||
- Pass to `PromptBuilder` when building prompts
|
||||
|
||||
**Files to Create/Modify**:
|
||||
- `src/cli/service/agent/editor_state.h` (new)
|
||||
- `src/cli/service/ai/prompt_builder.h/.cc` (modify)
|
||||
|
||||
### Phase 4: Refactoring
|
||||
|
||||
#### 4.1 ToolDispatcher Structured Output
|
||||
**Goal**: Return JSON instead of capturing stdout
|
||||
|
||||
**Current State**: `ToolDispatcher::Dispatch()` returns `absl::StatusOr<std::string>` by capturing stdout from command handlers.
|
||||
|
||||
**Proposed Changes**:
|
||||
1. Create `ToolResult` struct:
|
||||
```cpp
|
||||
struct ToolResult {
|
||||
std::string output; // Human-readable output
|
||||
nlohmann::json data; // Structured data (if applicable)
|
||||
bool success;
|
||||
std::vector<std::string> warnings;
|
||||
};
|
||||
```
|
||||
|
||||
2. Update command handlers to return `ToolResult`:
|
||||
- Modify base `CommandHandler` interface
|
||||
- Update each handler implementation
|
||||
- Keep backward compatibility with `OutputFormatter` for CLI
|
||||
|
||||
3. Update `ToolDispatcher::Dispatch()`:
|
||||
- Return `absl::StatusOr<ToolResult>`
|
||||
- Convert to JSON for API responses
|
||||
- Keep string output for CLI compatibility
|
||||
|
||||
**Files to Modify**:
|
||||
- `src/cli/service/agent/tool_dispatcher.h/.cc`
|
||||
- `src/cli/handlers/*/command_handlers.h/.cc` (all handlers)
|
||||
- `src/cli/service/agent/command_handler.h` (base interface)
|
||||
|
||||
**Migration Strategy**:
|
||||
- Add new `ExecuteStructured()` method alongside existing `Execute()`
|
||||
- Gradually migrate handlers
|
||||
- Keep old path for CLI until migration complete
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### Model Registry Usage Pattern
|
||||
```cpp
|
||||
// Register services
|
||||
auto& registry = cli::ModelRegistry::GetInstance();
|
||||
registry.RegisterService(std::make_shared<OllamaAIService>(ollama_config));
|
||||
registry.RegisterService(std::make_shared<GeminiAIService>(gemini_config));
|
||||
|
||||
// List all models
|
||||
auto models_or = registry.ListAllModels();
|
||||
// Returns unified list sorted by name
|
||||
```
|
||||
|
||||
### API Key Management
|
||||
- Gemini API key: Currently stored in `AgentConfigState::gemini_api_key`
|
||||
- Consider: Environment variable fallback, secure storage
|
||||
- Future: Support multiple API keys for different providers
|
||||
|
||||
### Thread Safety
|
||||
- `ModelRegistry` uses mutex for thread-safe access
|
||||
- `HttpServer` should handle concurrent requests (httplib supports this)
|
||||
- `ToolDispatcher` may need locking if shared across threads
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
### Phase 1 (Model Management)
|
||||
- [ ] Verify Ollama models appear in unified list
|
||||
- [ ] Verify Gemini models appear in unified list
|
||||
- [ ] Test model refresh with multiple providers
|
||||
- [ ] Test provider filtering in UI
|
||||
- [ ] Test model selection and configuration
|
||||
|
||||
### Phase 2 (API)
|
||||
- [ ] Test `/api/v1/models` endpoint
|
||||
- [ ] Test `/api/v1/chat` with different providers
|
||||
- [ ] Test `/api/v1/tool/*` endpoints
|
||||
- [ ] Test error handling (missing ROM, invalid tool, etc.)
|
||||
- [ ] Test concurrent requests
|
||||
- [ ] Test CORS if needed
|
||||
|
||||
### Phase 3 (Tools)
|
||||
- [ ] Test FileSystemTool with read operations
|
||||
- [ ] Test FileSystemTool write confirmation flow
|
||||
- [ ] Test BuildTool cmake/ninja execution
|
||||
- [ ] Test BuildTool error parsing
|
||||
- [ ] Test editor state injection into prompts
|
||||
|
||||
### Phase 4 (Refactoring)
|
||||
- [ ] Verify all handlers return structured output
|
||||
- [ ] Test API endpoints with new format
|
||||
- [ ] Verify CLI still works with old format
|
||||
- [ ] Performance test (no regressions)
|
||||
|
||||
## Known Issues
|
||||
|
||||
1. **UI Rendering**: `RenderModelConfigControls()` still has provider-specific code that should be unified
|
||||
2. **Model Info Display**: Some fields from `ModelInfo` (like `quantization`, `modified_at`) are not displayed in unified view
|
||||
3. **Error Handling**: Model listing failures are logged but don't prevent other providers from loading
|
||||
|
||||
## Next Steps (Priority Order)
|
||||
|
||||
1. **Complete UI unification** - Update `RenderModelConfigControls()` to use unified model list
|
||||
2. **Implement HTTP Server** - Start with basic server and `/api/v1/models` endpoint
|
||||
3. **Add chat endpoint** - Wire up `ConversationalAgentService` to API
|
||||
4. **Add tool endpoint** - Expose `ToolDispatcher` via API
|
||||
5. **Implement FileSystemTool** - Start with read-only operations
|
||||
6. **Implement BuildTool** - Basic cmake/ninja execution
|
||||
7. **Refactor ToolDispatcher** - Begin structured output migration
|
||||
|
||||
## References
|
||||
|
||||
- Plan document: `plan-yaze-api-agentic-workflow-enhancement.plan.md`
|
||||
- Model Registry: `src/cli/service/ai/model_registry.h`
|
||||
- AIService interface: `src/cli/service/ai/ai_service.h`
|
||||
- ToolDispatcher: `src/cli/service/agent/tool_dispatcher.h`
|
||||
- httplib docs: (in `ext/httplib/`)
|
||||
|
||||
## Questions for Next Developer
|
||||
|
||||
1. Should the HTTP server be enabled by default or require a flag?
|
||||
2. What port should be used? (8080 suggested, but configurable?)
|
||||
3. Should FileSystemTool require explicit user approval per operation or a "trusted scope"?
|
||||
4. Should BuildTool be limited to specific directories (e.g., `build/`) for safety?
|
||||
5. How should API authentication work? (API key? Localhost-only? None?)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-01-XX
|
||||
**Contact**: (to be filled)
|
||||
|
||||
45
docs/internal/agents/gh-actions-remote.md
Normal file
45
docs/internal/agents/gh-actions-remote.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# GitHub Actions Remote Workflow Documentation
|
||||
|
||||
This document describes how to trigger GitHub Actions workflows remotely, specifically focusing on the `ci.yml` workflow and its custom inputs.
|
||||
|
||||
## Triggering `ci.yml` Remotely
|
||||
|
||||
The `ci.yml` workflow can be triggered manually via the GitHub UI or programmatically using the GitHub API (or `gh` CLI) thanks to the `workflow_dispatch` event.
|
||||
|
||||
### Inputs
|
||||
|
||||
The `workflow_dispatch` event for `ci.yml` supports the following custom inputs:
|
||||
|
||||
- **`build_type`**:
|
||||
- **Description**: Specifies the CMake build type.
|
||||
- **Type**: `choice`
|
||||
- **Options**: `Debug`, `Release`, `RelWithDebInfo`
|
||||
- **Default**: `RelWithDebInfo`
|
||||
|
||||
- **`run_sanitizers`**:
|
||||
- **Description**: A boolean flag to enable or disable memory sanitizer runs.
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `false`
|
||||
|
||||
- **`upload_artifacts`**:
|
||||
- **Description**: A boolean flag to enable or disable uploading build artifacts.
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `false`
|
||||
|
||||
- **`enable_http_api_tests`**:
|
||||
- **Description**: **(NEW)** A boolean flag to enable or disable an additional step that runs HTTP API tests after the build. When set to `true`, a script (`scripts/agents/test-http-api.sh`) will be executed to validate the HTTP server (checking if the port is up and the health endpoint responds).
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `false`
|
||||
|
||||
### Example Usage (GitHub CLI)
|
||||
|
||||
To trigger the `ci.yml` workflow with custom inputs using the `gh` CLI:
|
||||
|
||||
```bash
|
||||
gh workflow run ci.yml -f build_type=Release -f enable_http_api_tests=true
|
||||
```
|
||||
|
||||
This command will:
|
||||
- Trigger the `ci.yml` workflow.
|
||||
- Set the `build_type` to `Release`.
|
||||
- Enable the HTTP API tests.
|
||||
45
docs/internal/agents/initiative-template.md
Normal file
45
docs/internal/agents/initiative-template.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# AI Initiative Template
|
||||
|
||||
Use this template when kicking off a sizable AI-driven effort (infrastructure, editor refactor,
|
||||
automation tooling, etc.). Keep the filled-out document alongside other planning notes and reference
|
||||
it from the coordination board.
|
||||
|
||||
```
|
||||
# <Initiative Title>
|
||||
|
||||
## Summary
|
||||
- Lead agent/persona:
|
||||
- Supporting agents:
|
||||
- Problem statement:
|
||||
- Success metrics:
|
||||
|
||||
## Scope
|
||||
- In scope:
|
||||
- Out of scope:
|
||||
- Dependencies / upstream projects:
|
||||
|
||||
## Risks & Mitigations
|
||||
- Risk 1 – mitigation
|
||||
- Risk 2 – mitigation
|
||||
|
||||
## Testing & Validation
|
||||
- Required test targets:
|
||||
- ROM/test data requirements:
|
||||
- Manual validation steps (if any):
|
||||
|
||||
## Documentation Impact
|
||||
- Public docs to update:
|
||||
- Internal docs/templates to update:
|
||||
- Coordination board entry link:
|
||||
- Helper scripts to use/log: `scripts/agents/smoke-build.sh`, `scripts/agents/run-tests.sh`, `scripts/agents/run-gh-workflow.sh`
|
||||
|
||||
## Timeline / Checkpoints
|
||||
- Milestone 1 (description, ETA)
|
||||
- Milestone 2 (description, ETA)
|
||||
```
|
||||
|
||||
After filling in the template:
|
||||
1. Check the coordination board for conflicts before starting work.
|
||||
2. Link the initiative file from your board entries so other agents can find details without copying
|
||||
sections into multiple docs.
|
||||
3. Archive or mark the initiative as complete when the success metrics are met.
|
||||
15
docs/internal/agents/personas.md
Normal file
15
docs/internal/agents/personas.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Agent Personas
|
||||
|
||||
Use these canonical identifiers when updating the
|
||||
[coordination board](coordination-board.md) or referencing responsibilities in other documents.
|
||||
|
||||
| Agent ID | Primary Focus | Notes |
|
||||
|-----------------|--------------------------------------------------------|-------|
|
||||
| `CLAUDE_CORE` | Core editor/engine refactors, renderer work, SDL/ImGui | Use when Claude tackles gameplay/editor features. |
|
||||
| `CLAUDE_AIINF` | AI infrastructure (`z3ed`, agents, gRPC automation) | Coordinates closely with Gemini automation agents. |
|
||||
| `CLAUDE_DOCS` | Documentation, onboarding guides, product notes | Keep docs synced with code changes and proposals. |
|
||||
| `GEMINI_AUTOM` | Automation/testing/CLI improvements, CI integrations | Handles scripting-heavy or test harness tasks. |
|
||||
| `CODEX` | Codex CLI assistant / overseer | Default persona; also monitors docs/build coordination when noted. |
|
||||
|
||||
Add new rows as additional personas are created. Every new persona must follow the protocol in
|
||||
`AGENTS.md` and post updates to the coordination board before starting work.
|
||||
85
docs/internal/handoff/ai-api-phase2-handoff.md
Normal file
85
docs/internal/handoff/ai-api-phase2-handoff.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# AI API & Agentic Workflow Enhancement - Phase 2 Handoff
|
||||
|
||||
**Date**: 2025-11-20
|
||||
**Status**: Phase 2 Implementation Complete
|
||||
**Previous Plan**: `docs/internal/AI_API_ENHANCEMENT_HANDOFF.md`
|
||||
|
||||
## Overview
|
||||
This handoff covers the completion of Phase 2, which focused on unifying the UI for model selection and implementing the initial HTTP API server foundation. The codebase is now ready for building and verifying the API endpoints.
|
||||
|
||||
## Completed Work
|
||||
|
||||
### 1. UI Unification (`src/app/editor/agent/agent_chat_widget.cc`)
|
||||
- **Unified Model List**: Replaced the separate Ollama/Gemini list logic with a single, unified list derived from `ModelRegistry`.
|
||||
- **Provider Badges**: Models in the list now display their provider (e.g., `[ollama]`, `[gemini]`).
|
||||
- **Contextual Configuration**:
|
||||
- If an **Ollama** model is selected, the "Ollama Host" input is displayed.
|
||||
- If a **Gemini** model is selected, the "API Key" input is displayed.
|
||||
- **Favorites & Presets**: Updated to work with the unified `ModelInfo` structure.
|
||||
|
||||
### 2. HTTP Server Implementation (`src/cli/service/api/`)
|
||||
- **`HttpServer` Class**:
|
||||
- Wraps `httplib::Server` running in a background `std::thread`.
|
||||
- Exposed via `Start(port)` and `Stop()` methods.
|
||||
- Graceful shutdown handling.
|
||||
- **API Handlers**:
|
||||
- `GET /api/v1/health`: Returns server status (JSON).
|
||||
- `GET /api/v1/models`: Returns list of available models from `ModelRegistry`.
|
||||
- **Integration**:
|
||||
- Updated `src/cli/agent.cmake` to include `http_server.cc`, `api_handlers.cc`, and `model_registry.cc`.
|
||||
- Updated `src/app/main.cc` to accept `--enable_api` and `--api_port` flags.
|
||||
|
||||
## Build & Test Instructions
|
||||
|
||||
### 1. Building
|
||||
The project uses CMake. The new files are automatically included in the `yaze_agent` library via `src/cli/agent.cmake`.
|
||||
|
||||
```bash
|
||||
# Generate build files (if not already done)
|
||||
cmake -B build -G Ninja
|
||||
|
||||
# Build the main application
|
||||
cmake --build build --target yaze_app
|
||||
```
|
||||
|
||||
### 2. Testing the UI
|
||||
1. Launch the editor:
|
||||
```bash
|
||||
./build/yaze_app --editor=Agent
|
||||
```
|
||||
2. Verify the **Model Configuration** panel:
|
||||
- You should see a single list of models.
|
||||
- Try searching for a model.
|
||||
- Select an Ollama model -> Verify "Host" input appears.
|
||||
- Select a Gemini model -> Verify "API Key" input appears.
|
||||
|
||||
### 3. Testing the API
|
||||
1. Launch the editor with API enabled:
|
||||
```bash
|
||||
./build/yaze_app --enable_api --api_port=8080
|
||||
```
|
||||
*(Check logs for "Starting API server on port 8080")*
|
||||
|
||||
2. Test Health Endpoint:
|
||||
```bash
|
||||
curl -v http://localhost:8080/api/v1/health
|
||||
# Expected: {"status":"ok", "version":"1.0", ...}
|
||||
```
|
||||
|
||||
3. Test Models Endpoint:
|
||||
```bash
|
||||
curl -v http://localhost:8080/api/v1/models
|
||||
# Expected: {"models": [{"name": "...", "provider": "..."}], "count": ...}
|
||||
```
|
||||
|
||||
## Next Steps (Phase 3 & 4)
|
||||
|
||||
### Phase 3: Tool Expansion
|
||||
- **FileSystemTool**: Implement safe file read/write operations (`src/cli/handlers/tools/filesystem_commands.h`).
|
||||
- **BuildTool**: Implement cmake/ninja triggers.
|
||||
- **Editor Integration**: Inject editor state (open files, errors) into the agent context.
|
||||
|
||||
### Phase 4: Structured Output
|
||||
- Refactor `ToolDispatcher` to return JSON objects instead of capturing stdout strings.
|
||||
- Update API to expose a `/api/v1/chat` endpoint that returns these structured responses.
|
||||
|
||||
68
docs/internal/roadmaps/2025-11-build-performance.md
Normal file
68
docs/internal/roadmaps/2025-11-build-performance.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Build Performance & Agent-Friendly Tooling (November 2025)
|
||||
|
||||
Status: **Draft**
|
||||
Owner: CODEX (open to CLAUDE/GEMINI participation)
|
||||
|
||||
## Goals
|
||||
- Reduce incremental build times on all platforms by tightening target boundaries, isolating optional
|
||||
components, and providing cache-friendly presets.
|
||||
- Allow long-running or optional tasks (e.g., asset generation, documentation, verification scripts)
|
||||
to run asynchronously or on-demand so agents don’t block on them.
|
||||
- Provide monitoring/metrics hooks so agents and humans can see where build time is spent.
|
||||
- Organize helper scripts (build, verification, CI triggers) so agents can call them predictably.
|
||||
|
||||
## Plan Overview
|
||||
|
||||
### 1. Library Scoping & Optional Targets
|
||||
1. Audit `src/CMakeLists.txt` and per-module cmake files for broad `add_subdirectory` usage.
|
||||
- Identify libraries that can be marked `EXCLUDE_FROM_ALL` and only built when needed (e.g.,
|
||||
optional tools, emulator targets).
|
||||
- Leverage `YAZE_MINIMAL_BUILD`, `YAZE_BUILD_Z3ED`, etc., but ensure presets reflect the smallest
|
||||
viable dependency tree.
|
||||
2. Split heavy modules (e.g., `app/editor`, `app/emu`) into more granular targets if they are
|
||||
frequently touched independently.
|
||||
3. Add caching hints (ccache, sccache) in the build scripts/presets for all platforms.
|
||||
|
||||
### 2. Background / Async Tasks
|
||||
1. Move long-running scripts (asset bundling, doc generation, lints) into optional targets invoked by
|
||||
a convenience meta-target (e.g., `yaze_extras`) so normal builds stay lean.
|
||||
2. Provide `scripts/run-background-tasks.sh` that uses `nohup`/`start` to launch doc builds, GH
|
||||
workflow dispatch, or other heavy processes asynchronously; log their status for monitoring.
|
||||
3. Ensure CI workflows skip optional tasks unless explicitly requested (e.g., via workflow inputs).
|
||||
|
||||
### 3. Monitoring & Metrics
|
||||
1. Add a lightweight timing report to `scripts/verify-build-environment.*` or a new
|
||||
`scripts/measure-build.sh` that runs `cmake --build` with `--trace-expand`/`ninja -d stats` and
|
||||
reports hotspots.
|
||||
2. Integrate a summary step in CI (maybe a bash step) that records build duration per preset and
|
||||
uploads as an artifact or comment.
|
||||
3. Document how agents should capture metrics when running builds (e.g., use `time` wrappers, log
|
||||
output to `logs/build_<preset>.log`).
|
||||
|
||||
### 4. Agent-Friendly Script Organization
|
||||
1. Gather recurring helper commands into `scripts/agents/`:
|
||||
- `run-gh-workflow.sh` (wrapper around `gh workflow run`)
|
||||
- `smoke-build.sh <preset>` (configures & builds a preset in a dedicated directory, records time)
|
||||
- `run-tests.sh <preset> <labels>` (standardizes test selections)
|
||||
2. Provide short README in `scripts/agents/` explaining parameters, sample usage, and expected output
|
||||
files for logging back to the coordination board.
|
||||
3. Update `AGENTS.md` to reference these scripts so every persona knows the canonical tooling.
|
||||
|
||||
### 5. Deliverables / Tracking
|
||||
- Update CMake targets/presets to reflect modular build improvements.
|
||||
- New scripts under `scripts/agents/` + documentation.
|
||||
- Monitoring notes in CI (maybe via job summary) and local scripts.
|
||||
- Coordination board entries per major milestone (library scoping, background tooling, metrics,
|
||||
script rollout).
|
||||
|
||||
## Dependencies / Risks
|
||||
- Coordinate with CLAUDE_AIINF when touching presets or build scripts—they may modify the same files
|
||||
for AI workflow fixes.
|
||||
- When changing CMake targets, ensure existing presets still configure successfully (run verification
|
||||
scripts + smoke builds on mac/linux/win).
|
||||
- Adding background tasks/scripts should not introduce new global dependencies; use POSIX Bash and
|
||||
PowerShell equivalents where required.
|
||||
## Windows Stability Focus (New)
|
||||
- **Tooling verification**: expand `scripts/verify-build-environment.ps1` to check for Visual Studio workload, Ninja, and vcpkg caches so Windows builds fail fast when the environment is incomplete.
|
||||
- **CMake structure**: ensure optional components (HTTP API, emulator, CLI helpers) are behind explicit options and do not affect default Windows presets; verify each target links the right runtime/library deps even when `YAZE_ENABLE_*` flags change.
|
||||
- **Preset validation**: add Windows smoke builds (Ninja + VS) to the helper scripts/CI so we can trigger focused runs when changes land.
|
||||
46
docs/internal/roadmaps/2025-11-modernization.md
Normal file
46
docs/internal/roadmaps/2025-11-modernization.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Modernization Plan – November 2025
|
||||
|
||||
Status: **Draft**
|
||||
Owner: Core tooling team
|
||||
Scope: `core/asar_wrapper`, CLI/GUI flag system, project persistence, docs
|
||||
|
||||
## Context
|
||||
- The Asar integration is stubbed out (`src/core/asar_wrapper.cc`), yet the GUI, CLI, and docs still advertise a working assembler workflow.
|
||||
- The GUI binary (`yaze`) still relies on the legacy `util::Flag` parser while the rest of the tooling has moved to Abseil flags, leading to inconsistent UX and duplicated parsing logic.
|
||||
- Project metadata initialization uses `std::localtime` (`src/core/project.cc`), which is not thread-safe and can race when the agent/automation stack spawns concurrent project creation tasks.
|
||||
- Public docs promise Dungeon Editor rendering details and “Examples & Recipes,” but those sections are either marked TODO or empty.
|
||||
|
||||
## Goals
|
||||
1. Restore a fully functioning Asar toolchain across GUI/CLI and make sure automated tests cover it.
|
||||
2. Unify flag parsing by migrating the GUI binary (and remaining utilities) to Abseil flags, then retire `util::flag`.
|
||||
3. Harden project/workspace persistence by replacing unsafe time handling and improving error propagation during project bootstrap.
|
||||
4. Close the documentation gaps so the Dungeon Editor guide reflects current rendering, and the `docs/public/examples/` tree provides actual recipes.
|
||||
|
||||
## Work Breakdown
|
||||
|
||||
### 1. Asar Restoration
|
||||
- Fix the Asar CMake integration under `ext/asar` and link it back into `yaze_core_lib`.
|
||||
- Re-implement `AsarWrapper` methods (patch, symbol extraction, validation) and add regression tests in `test/integration/asar_*`.
|
||||
- Update `z3ed`/GUI code paths to surface actionable errors when the assembler fails.
|
||||
- Once complete, scrub docs/README claims to ensure they match the restored behavior.
|
||||
|
||||
### 2. Flag Standardization
|
||||
- Replace `DEFINE_FLAG` usage in `src/app/main.cc` with `ABSL_FLAG` + `absl::ParseCommandLine`.
|
||||
- Delete `util::flag.*` and migrate any lingering consumers (e.g., dev tools) to Abseil.
|
||||
- Document the shared flag set in a single reference (README + `docs/public/developer/debug-flags.md`).
|
||||
|
||||
### 3. Project Persistence Hardening
|
||||
- Swap `std::localtime` for `absl::Time` or platform-safe helpers and handle failures explicitly.
|
||||
- Ensure directory creation and file writes bubble errors back to the UI/CLI instead of silently failing.
|
||||
- Add regression tests that spawn concurrent project creations (possibly via the CLI) to confirm deterministic metadata.
|
||||
|
||||
### 4. Documentation Updates
|
||||
- Finish the Dungeon Editor rendering pipeline description (remove the TODO block) so it reflects the current draw path.
|
||||
- Populate `docs/public/examples/` with at least a handful of ROM-editing recipes (overworld tile swap, dungeon entrance move, palette tweak, CLI plan/accept flow).
|
||||
- Add a short “automation journey” that links `README` → gRPC harness (`src/app/service/imgui_test_harness_service.cc`) → `z3ed` agent commands.
|
||||
|
||||
## Exit Criteria
|
||||
- `AsarWrapper` integration tests green on macOS/Linux/Windows runners.
|
||||
- No binaries depend on `util::flag`; `absl::flags` is the single source of truth.
|
||||
- Project creation succeeds under parallel stress and metadata timestamps remain valid.
|
||||
- Public docs no longer contain TODO placeholders or empty directories for the sections listed above.
|
||||
80
docs/public/build/quick-reference.md
Normal file
80
docs/public/build/quick-reference.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Build & Test Quick Reference
|
||||
|
||||
Use this document as the single source of truth for configuring, building, and testing YAZE across
|
||||
platforms. Other guides (README, CLAUDE.md, GEMINI.md, etc.) should link here instead of duplicating
|
||||
steps.
|
||||
|
||||
## 1. Environment Prep
|
||||
- Clone with submodules: `git clone --recursive https://github.com/scawful/yaze.git`
|
||||
- Run the verifier once per machine:
|
||||
- macOS/Linux: `./scripts/verify-build-environment.sh --fix`
|
||||
- Windows PowerShell: `.\scripts\verify-build-environment.ps1 -FixIssues`
|
||||
|
||||
## 2. Build Presets
|
||||
Use `cmake --preset <name>` followed by `cmake --build --preset <name> [--target …]`.
|
||||
|
||||
| Preset | Platform(s) | Notes |
|
||||
|-------------|-------------|-------|
|
||||
| `mac-dbg`, `lin-dbg`, `win-dbg` | macOS/Linux/Windows | Standard debug builds, tests on by default. |
|
||||
| `mac-ai`, `lin-ai`, `win-ai` | macOS/Linux/Windows | Enables gRPC, agent UI, `z3ed`, and AI runtime. |
|
||||
| `mac-rel`, `lin-rel`, `win-rel` | macOS/Linux/Windows | Optimized release builds. |
|
||||
| `mac-dev`, `lin-dev`, `win-dev` | macOS/Linux/Windows | Development builds with ROM-dependent tests enabled. |
|
||||
| `mac-uni` | macOS | Universal binary (ARM64 + x86_64) for distribution. |
|
||||
| `ci-*` presets | Platform-specific | Mirrors CI matrix; see `CMakePresets.json`. |
|
||||
|
||||
**Verbose builds**: add `-v` suffix (e.g., `mac-dbg-v`, `lin-dbg-v`, `win-dbg-v`) to turn off compiler warning suppression.
|
||||
|
||||
## 3. AI/Assistant Build Policy
|
||||
- Human developers typically use `build` or `build_test` directories.
|
||||
- AI assistants **must use dedicated directories** (`build_ai`, `build_agent`, etc.) to avoid
|
||||
clobbering user builds.
|
||||
- When enabling AI features, prefer the `*-ai` presets and target only the binaries you need
|
||||
(`yaze`, `z3ed`, `yaze_test`, …).
|
||||
- Windows helpers: use `scripts/agents/windows-smoke-build.ps1` for quick builds and `scripts/agents/run-tests.sh` (or its PowerShell equivalent) for test runs so preset + generator settings stay consistent.
|
||||
|
||||
## 4. Common Commands
|
||||
```bash
|
||||
# Debug GUI build (macOS)
|
||||
cmake --preset mac-dbg
|
||||
cmake --build --preset mac-dbg --target yaze
|
||||
|
||||
# Debug GUI build (Linux)
|
||||
cmake --preset lin-dbg
|
||||
cmake --build --preset lin-dbg --target yaze
|
||||
|
||||
# Debug GUI build (Windows)
|
||||
cmake --preset win-dbg
|
||||
cmake --build --preset win-dbg --target yaze
|
||||
|
||||
# AI-enabled build with gRPC (macOS)
|
||||
cmake --preset mac-ai
|
||||
cmake --build --preset mac-ai --target yaze z3ed
|
||||
|
||||
# AI-enabled build with gRPC (Linux)
|
||||
cmake --preset lin-ai
|
||||
cmake --build --preset lin-ai --target yaze z3ed
|
||||
|
||||
# AI-enabled build with gRPC (Windows)
|
||||
cmake --preset win-ai
|
||||
cmake --build --preset win-ai --target yaze z3ed
|
||||
```
|
||||
|
||||
## 5. Testing
|
||||
- Build target: `cmake --build --preset <preset> --target yaze_test`
|
||||
- Run all tests: `./build/bin/yaze_test`
|
||||
- Filtered runs:
|
||||
- `./build/bin/yaze_test --unit`
|
||||
- `./build/bin/yaze_test --integration`
|
||||
- `./build/bin/yaze_test --e2e --show-gui`
|
||||
- `./build/bin/yaze_test --rom-dependent --rom-path path/to/zelda3.sfc`
|
||||
- Preset-based ctest: `ctest --preset dev`
|
||||
|
||||
Environment variables:
|
||||
- `YAZE_TEST_ROM_PATH` – default ROM for ROM-dependent tests.
|
||||
- `YAZE_SKIP_ROM_TESTS`, `YAZE_ENABLE_UI_TESTS` – gate expensive suites.
|
||||
|
||||
## 6. Troubleshooting & References
|
||||
- Detailed troubleshooting: `docs/public/build/troubleshooting.md`
|
||||
- Platform compatibility: `docs/public/build/platform-compatibility.md`
|
||||
- Internal agents must follow coordination protocol in
|
||||
`docs/internal/agents/coordination-board.md` before running builds/tests.
|
||||
49
docs/public/examples/README.md
Normal file
49
docs/public/examples/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Examples & Recipes
|
||||
|
||||
Short, task-focused snippets for everyday YAZE workflows. These examples supplement the primary
|
||||
guides (Getting Started, z3ed CLI, Dungeon/Overworld editors) and should remain concise. When in
|
||||
doubt, link back to the relevant guide instead of duplicating long explanations.
|
||||
|
||||
## 1. Launching Common Editors
|
||||
```bash
|
||||
# Open YAZE directly in the Dungeon editor with room cards preset
|
||||
./build/bin/yaze --rom_file=zelda3.sfc \
|
||||
--editor=Dungeon \
|
||||
--cards="Rooms List,Room Graphics,Object Editor"
|
||||
|
||||
# Jump to an Overworld map from the CLI/TUI companion
|
||||
./build/bin/z3ed overworld describe-map --map 0x80 --rom zelda3.sfc
|
||||
```
|
||||
|
||||
## 2. AI/Automation Recipes
|
||||
```bash
|
||||
# Generate an AI plan to reposition an entrance, but do not apply yet
|
||||
./build/bin/z3ed agent plan \
|
||||
--rom zelda3.sfc \
|
||||
--prompt "Move the desert palace entrance 2 tiles north" \
|
||||
--sandbox
|
||||
|
||||
# Resume the plan and apply it once reviewed
|
||||
./build/bin/z3ed agent accept --proposal-id <ID> --rom zelda3.sfc --sandbox
|
||||
```
|
||||
|
||||
## 3. Building & Testing Snippets
|
||||
```bash
|
||||
# Debug build with tests
|
||||
cmake --preset mac-dbg
|
||||
cmake --build --preset mac-dbg --target yaze yaze_test
|
||||
./build/bin/yaze_test --unit
|
||||
|
||||
# AI-focused build in a dedicated directory (recommended for assistants)
|
||||
cmake --preset mac-ai -B build_ai
|
||||
cmake --build build_ai --target yaze z3ed
|
||||
```
|
||||
|
||||
## 4. Quick Verification
|
||||
- Run `./scripts/verify-build-environment.sh --fix` (or the PowerShell variant on Windows) whenever
|
||||
pulling major build changes.
|
||||
- See the [Build & Test Quick Reference](../build/quick-reference.md) for the canonical list of
|
||||
commands and testing recipes.
|
||||
|
||||
Want to contribute another recipe? Add it here with a short description and reference the relevant
|
||||
guide so the examples stay focused.
|
||||
30
scripts/agents/README.md
Normal file
30
scripts/agents/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Agent Helper Scripts
|
||||
|
||||
| Script | Description |
|
||||
|--------|-------------|
|
||||
| `run-gh-workflow.sh` | Wrapper for `gh workflow run`, prints the run URL for easy tracking. |
|
||||
| `smoke-build.sh` | Runs `cmake --preset` configure/build in place and reports timing. |
|
||||
| `run-tests.sh` | Configures the preset (if needed), builds `yaze_test`, and runs `ctest` with optional args. |
|
||||
| `test-http-api.sh` | Polls the HTTP API `/api/v1/health` endpoint using curl (defaults to localhost:8080). |
|
||||
| `windows-smoke-build.ps1` | PowerShell variant of the smoke build helper for Visual Studio/Ninja presets on Windows. |
|
||||
|
||||
Usage examples:
|
||||
```bash
|
||||
# Trigger CI workflow with artifacts and HTTP API tests enabled
|
||||
scripts/agents/run-gh-workflow.sh ci.yml --ref develop upload_artifacts=true enable_http_api_tests=true
|
||||
|
||||
# Smoke build mac-ai preset
|
||||
scripts/agents/smoke-build.sh mac-ai
|
||||
|
||||
# Build & run tests for mac-dbg preset with verbose ctest output
|
||||
scripts/agents/run-tests.sh mac-dbg --output-on-failure
|
||||
|
||||
# Check HTTP API health (defaults to localhost:8080)
|
||||
scripts/agents/test-http-api.sh
|
||||
|
||||
# Windows smoke build using PowerShell
|
||||
pwsh -File scripts/agents/windows-smoke-build.ps1 -Preset win-ai -Target z3ed
|
||||
```
|
||||
|
||||
When invoking these scripts, log the results on the coordination board so other agents know which
|
||||
workflows/builds were triggered and where to find artifacts/logs.
|
||||
50
scripts/agents/run-gh-workflow.sh
Normal file
50
scripts/agents/run-gh-workflow.sh
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
# Wrapper for triggering GitHub Actions workflows via gh CLI.
|
||||
# Usage: scripts/agents/run-gh-workflow.sh <workflow_file> [--ref <ref>] [key=value ...]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if ! command -v gh >/dev/null 2>&1; then
|
||||
echo "error: gh CLI is required (https://cli.github.com/)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "Usage: $0 <workflow_file> [--ref <ref>] [key=value ...]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
WORKFLOW="$1"
|
||||
shift
|
||||
|
||||
REF=""
|
||||
INPUT_ARGS=()
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--ref)
|
||||
REF="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
INPUT_ARGS+=("-f" "$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
CMD=(gh workflow run "$WORKFLOW")
|
||||
if [[ -n "$REF" ]]; then
|
||||
CMD+=("--ref" "$REF")
|
||||
fi
|
||||
if [[ ${#INPUT_ARGS[@]} -gt 0 ]]; then
|
||||
CMD+=("${INPUT_ARGS[@]}")
|
||||
fi
|
||||
|
||||
echo "+ ${CMD[*]}"
|
||||
"${CMD[@]}"
|
||||
|
||||
RUN_URL=$(gh run list --workflow "$WORKFLOW" --limit 1 --json url -q '.[0].url')
|
||||
if [[ -n "$RUN_URL" ]]; then
|
||||
echo "Triggered workflow. Track progress at: $RUN_URL"
|
||||
fi
|
||||
81
scripts/agents/run-tests.sh
Executable file
81
scripts/agents/run-tests.sh
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bash
|
||||
# Helper script to configure, build, and run tests for a given CMake preset.
|
||||
# Usage: scripts/agents/run-tests.sh <preset> [ctest-args...]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "Usage: $0 <preset> [ctest-args...]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PRESET="$1"
|
||||
shift
|
||||
|
||||
echo "Configuring preset: $PRESET"
|
||||
cmake --preset "$PRESET" || { echo "Configure failed for preset: $PRESET"; exit 1; }
|
||||
|
||||
ROOT_DIR=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
||||
read -r GENERATOR BUILD_CONFIG <<EOF
|
||||
$(python - <<'PY' "$PRESET" "$ROOT_DIR"
|
||||
import json, sys, os
|
||||
preset = sys.argv[1]
|
||||
root = sys.argv[2]
|
||||
with open(os.path.join(root, "CMakePresets.json")) as f:
|
||||
data = json.load(f)
|
||||
configure = {p["name"]: p for p in data.get("configurePresets", [])}
|
||||
build = {p["name"]: p for p in data.get("buildPresets", [])}
|
||||
|
||||
def parents(entry):
|
||||
inherits = entry.get("inherits", [])
|
||||
if isinstance(inherits, str):
|
||||
inherits = [inherits]
|
||||
return inherits
|
||||
|
||||
def resolve_generator(name, seen=None):
|
||||
if seen is None:
|
||||
seen = set()
|
||||
if name in seen:
|
||||
return None
|
||||
seen.add(name)
|
||||
entry = configure.get(name)
|
||||
if not entry:
|
||||
return None
|
||||
gen = entry.get("generator")
|
||||
if gen:
|
||||
return gen
|
||||
for parent in parents(entry):
|
||||
gen = resolve_generator(parent, seen)
|
||||
if gen:
|
||||
return gen
|
||||
return None
|
||||
|
||||
generator = resolve_generator(preset)
|
||||
build_preset = build.get(preset, {})
|
||||
config = build_preset.get("configuration")
|
||||
if not config:
|
||||
entry = configure.get(preset, {})
|
||||
cache = entry.get("cacheVariables", {})
|
||||
config = cache.get("CMAKE_BUILD_TYPE", "Debug")
|
||||
|
||||
print(generator or "")
|
||||
print(config or "")
|
||||
PY)
|
||||
EOF
|
||||
|
||||
echo "Building tests for preset: $PRESET"
|
||||
BUILD_CMD=(cmake --build --preset "$PRESET")
|
||||
if [[ "$GENERATOR" == *"Visual Studio"* && -n "$BUILD_CONFIG" ]]; then
|
||||
BUILD_CMD+=(--config "$BUILD_CONFIG")
|
||||
fi
|
||||
"${BUILD_CMD[@]}" || { echo "Build failed for preset: $PRESET"; exit 1; }
|
||||
|
||||
if ctest --preset "$PRESET" --show-only >/dev/null 2>&1; then
|
||||
echo "Running tests for preset: $PRESET"
|
||||
ctest --preset "$PRESET" "$@"
|
||||
else
|
||||
echo "Test preset '$PRESET' not found, falling back to 'all' tests."
|
||||
ctest --preset all "$@"
|
||||
fi
|
||||
|
||||
echo "All tests passed for preset: $PRESET"
|
||||
19
scripts/agents/smoke-build.sh
Normal file
19
scripts/agents/smoke-build.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
# Quick smoke build for a given preset in an isolated directory with timing info.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "Usage: $0 <preset> [build_dir]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PRESET="$1"
|
||||
|
||||
START=$(date +%s)
|
||||
cmake --preset "$PRESET"
|
||||
cmake --build --preset "$PRESET"
|
||||
END=$(date +%s)
|
||||
|
||||
ELAPSED=$((END - START))
|
||||
echo "Smoke build '$PRESET' completed in ${ELAPSED}s"
|
||||
28
scripts/agents/test-http-api.sh
Executable file
28
scripts/agents/test-http-api.sh
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
# Basic health check for the HTTP API server.
|
||||
# Usage: scripts/agents/test-http-api.sh [host] [port]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
HOST="${1:-127.0.0.1}"
|
||||
PORT="${2:-8080}"
|
||||
URL="http://${HOST}:${PORT}/api/v1/health"
|
||||
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
echo "error: curl is required to test the HTTP API" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Checking HTTP API health endpoint at ${URL}"
|
||||
|
||||
for attempt in {1..10}; do
|
||||
if curl -fsS "${URL}" >/dev/null; then
|
||||
echo "HTTP API responded successfully (attempt ${attempt})"
|
||||
exit 0
|
||||
fi
|
||||
echo "Attempt ${attempt} failed; retrying..."
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "error: HTTP API did not respond at ${URL}" >&2
|
||||
exit 1
|
||||
70
scripts/agents/windows-smoke-build.ps1
Normal file
70
scripts/agents/windows-smoke-build.ps1
Normal file
@@ -0,0 +1,70 @@
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Preset,
|
||||
[string]$Target = ""
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$repoRoot = Resolve-Path "$PSScriptRoot/.."
|
||||
Set-Location $repoRoot
|
||||
|
||||
function Get-GeneratorAndConfig {
|
||||
param([string]$PresetName)
|
||||
|
||||
$jsonPath = Join-Path $repoRoot "CMakePresets.json"
|
||||
$data = Get-Content $jsonPath -Raw | ConvertFrom-Json
|
||||
$configurePresets = @{}
|
||||
foreach ($preset in $data.configurePresets) {
|
||||
$configurePresets[$preset.name] = $preset
|
||||
}
|
||||
|
||||
$buildPresets = @{}
|
||||
foreach ($preset in $data.buildPresets) {
|
||||
$buildPresets[$preset.name] = $preset
|
||||
}
|
||||
|
||||
function Resolve-Generator([string]$name, [hashtable]$seen) {
|
||||
if ($seen.ContainsKey($name)) { return $null }
|
||||
$seen[$name] = $true
|
||||
if (-not $configurePresets.ContainsKey($name)) { return $null }
|
||||
$entry = $configurePresets[$name]
|
||||
if ($entry.generator) { return $entry.generator }
|
||||
$inherits = $entry.inherits
|
||||
if ($inherits -is [string]) { $inherits = @($inherits) }
|
||||
foreach ($parent in $inherits) {
|
||||
$gen = Resolve-Generator $parent $seen
|
||||
if ($gen) { return $gen }
|
||||
}
|
||||
return $null
|
||||
}
|
||||
|
||||
$generator = Resolve-Generator $PresetName @{}
|
||||
|
||||
$config = $null
|
||||
if ($buildPresets.ContainsKey($PresetName) -and $buildPresets[$PresetName].configuration) {
|
||||
$config = $buildPresets[$PresetName].configuration
|
||||
} elseif ($configurePresets.ContainsKey($PresetName)) {
|
||||
$cache = $configurePresets[$PresetName].cacheVariables
|
||||
if ($cache.CMAKE_BUILD_TYPE) { $config = $cache.CMAKE_BUILD_TYPE }
|
||||
}
|
||||
|
||||
return @{ Generator = $generator; Configuration = $config }
|
||||
}
|
||||
|
||||
Write-Host "Configuring preset: $Preset"
|
||||
cmake --preset $Preset
|
||||
|
||||
$info = Get-GeneratorAndConfig -PresetName $Preset
|
||||
$buildCmd = @("cmake", "--build", "--preset", $Preset)
|
||||
if ($Target) { $buildCmd += @("--target", $Target) }
|
||||
if ($info.Generator -like "*Visual Studio*" -and $info.Configuration) {
|
||||
$buildCmd += @("--config", $info.Configuration)
|
||||
}
|
||||
|
||||
Write-Host "Building preset: $Preset"
|
||||
Write-Host "+ $($buildCmd -join ' ')"
|
||||
& $buildCmd
|
||||
|
||||
Write-Host "Smoke build completed for preset: $Preset"
|
||||
@@ -125,12 +125,13 @@ target_link_libraries(yaze_gfx_render PUBLIC
|
||||
${YAZE_SDL2_TARGETS}
|
||||
)
|
||||
|
||||
# Layer 3c: Debug tools (depends on types only at this level)
|
||||
# Layer 3c: Debug tools (depends on types, render, and resource)
|
||||
add_library(yaze_gfx_debug STATIC ${GFX_DEBUG_SRC})
|
||||
configure_gfx_library(yaze_gfx_debug)
|
||||
target_link_libraries(yaze_gfx_debug PUBLIC
|
||||
yaze_gfx_types
|
||||
yaze_gfx_resource
|
||||
yaze_gfx_render
|
||||
ImGui
|
||||
${YAZE_SDL2_TARGETS}
|
||||
)
|
||||
|
||||
BIN
zelda3.sfc
Normal file
BIN
zelda3.sfc
Normal file
Binary file not shown.
Reference in New Issue
Block a user