backend-infra-engineer: Release v0.3.2 snapshot
This commit is contained in:
236
src/protos/canvas_automation.proto
Normal file
236
src/protos/canvas_automation.proto
Normal file
@@ -0,0 +1,236 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package yaze.proto;
|
||||
|
||||
// ============================================================================
|
||||
// Canvas Automation Service
|
||||
// ============================================================================
|
||||
// Provides remote control of canvas operations for:
|
||||
// - AI agents via tool calls
|
||||
// - ImGuiTestHarness automation
|
||||
// - Remote GUI testing and validation
|
||||
// - Batch scripting workflows
|
||||
// - Coordinate conversion independent of zoom/scroll
|
||||
//
|
||||
// All operations use logical tile coordinates, not pixel coordinates.
|
||||
// This ensures commands work consistently regardless of UI zoom level.
|
||||
|
||||
service CanvasAutomation {
|
||||
// Tile Operations
|
||||
rpc SetTile(SetTileRequest) returns (SetTileResponse);
|
||||
rpc GetTile(GetTileRequest) returns (GetTileResponse);
|
||||
rpc SetTiles(SetTilesRequest) returns (SetTilesResponse);
|
||||
|
||||
// Selection Operations
|
||||
rpc SelectTile(SelectTileRequest) returns (SelectTileResponse);
|
||||
rpc SelectTileRect(SelectTileRectRequest) returns (SelectTileRectResponse);
|
||||
rpc GetSelection(GetSelectionRequest) returns (GetSelectionResponse);
|
||||
rpc ClearSelection(ClearSelectionRequest) returns (ClearSelectionResponse);
|
||||
|
||||
// View Operations
|
||||
rpc ScrollToTile(ScrollToTileRequest) returns (ScrollToTileResponse);
|
||||
rpc CenterOn(CenterOnRequest) returns (CenterOnResponse);
|
||||
rpc SetZoom(SetZoomRequest) returns (SetZoomResponse);
|
||||
rpc GetZoom(GetZoomRequest) returns (GetZoomResponse);
|
||||
|
||||
// Query Operations
|
||||
rpc GetDimensions(GetDimensionsRequest) returns (GetDimensionsResponse);
|
||||
rpc GetVisibleRegion(GetVisibleRegionRequest) returns (GetVisibleRegionResponse);
|
||||
rpc IsTileVisible(IsTileVisibleRequest) returns (IsTileVisibleResponse);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Common Types
|
||||
// ============================================================================
|
||||
|
||||
message TileCoord {
|
||||
int32 x = 1;
|
||||
int32 y = 2;
|
||||
}
|
||||
|
||||
message TileData {
|
||||
int32 x = 1;
|
||||
int32 y = 2;
|
||||
int32 tile_id = 3;
|
||||
}
|
||||
|
||||
message Rect {
|
||||
int32 x1 = 1;
|
||||
int32 y1 = 2;
|
||||
int32 x2 = 3;
|
||||
int32 y2 = 4;
|
||||
}
|
||||
|
||||
message Dimensions {
|
||||
int32 width_tiles = 1;
|
||||
int32 height_tiles = 2;
|
||||
int32 tile_size = 3;
|
||||
}
|
||||
|
||||
message VisibleRegion {
|
||||
int32 min_x = 1;
|
||||
int32 min_y = 2;
|
||||
int32 max_x = 3;
|
||||
int32 max_y = 4;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Tile Operations
|
||||
// ============================================================================
|
||||
|
||||
message SetTileRequest {
|
||||
string canvas_id = 1;
|
||||
int32 x = 2;
|
||||
int32 y = 3;
|
||||
int32 tile_id = 4;
|
||||
}
|
||||
|
||||
message SetTileResponse {
|
||||
bool success = 1;
|
||||
string error = 2;
|
||||
}
|
||||
|
||||
message GetTileRequest {
|
||||
string canvas_id = 1;
|
||||
int32 x = 2;
|
||||
int32 y = 3;
|
||||
}
|
||||
|
||||
message GetTileResponse {
|
||||
int32 tile_id = 1;
|
||||
bool success = 2;
|
||||
string error = 3;
|
||||
}
|
||||
|
||||
message SetTilesRequest {
|
||||
string canvas_id = 1;
|
||||
repeated TileData tiles = 2;
|
||||
}
|
||||
|
||||
message SetTilesResponse {
|
||||
bool success = 1;
|
||||
int32 tiles_painted = 2;
|
||||
string error = 3;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Selection Operations
|
||||
// ============================================================================
|
||||
|
||||
message SelectTileRequest {
|
||||
string canvas_id = 1;
|
||||
int32 x = 2;
|
||||
int32 y = 3;
|
||||
}
|
||||
|
||||
message SelectTileResponse {
|
||||
bool success = 1;
|
||||
string error = 2;
|
||||
}
|
||||
|
||||
message SelectTileRectRequest {
|
||||
string canvas_id = 1;
|
||||
Rect rect = 2;
|
||||
}
|
||||
|
||||
message SelectTileRectResponse {
|
||||
bool success = 1;
|
||||
int32 tiles_selected = 2;
|
||||
string error = 3;
|
||||
}
|
||||
|
||||
message GetSelectionRequest {
|
||||
string canvas_id = 1;
|
||||
}
|
||||
|
||||
message GetSelectionResponse {
|
||||
bool has_selection = 1;
|
||||
repeated TileCoord selected_tiles = 2;
|
||||
TileCoord selection_start = 3;
|
||||
TileCoord selection_end = 4;
|
||||
}
|
||||
|
||||
message ClearSelectionRequest {
|
||||
string canvas_id = 1;
|
||||
}
|
||||
|
||||
message ClearSelectionResponse {
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// View Operations
|
||||
// ============================================================================
|
||||
|
||||
message ScrollToTileRequest {
|
||||
string canvas_id = 1;
|
||||
int32 x = 2;
|
||||
int32 y = 3;
|
||||
bool center = 4;
|
||||
}
|
||||
|
||||
message ScrollToTileResponse {
|
||||
bool success = 1;
|
||||
string error = 2;
|
||||
}
|
||||
|
||||
message CenterOnRequest {
|
||||
string canvas_id = 1;
|
||||
int32 x = 2;
|
||||
int32 y = 3;
|
||||
}
|
||||
|
||||
message CenterOnResponse {
|
||||
bool success = 1;
|
||||
string error = 2;
|
||||
}
|
||||
|
||||
message SetZoomRequest {
|
||||
string canvas_id = 1;
|
||||
float zoom = 2;
|
||||
}
|
||||
|
||||
message SetZoomResponse {
|
||||
bool success = 1;
|
||||
float actual_zoom = 2; // May be clamped
|
||||
string error = 3;
|
||||
}
|
||||
|
||||
message GetZoomRequest {
|
||||
string canvas_id = 1;
|
||||
}
|
||||
|
||||
message GetZoomResponse {
|
||||
float zoom = 1;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Query Operations
|
||||
// ============================================================================
|
||||
|
||||
message GetDimensionsRequest {
|
||||
string canvas_id = 1;
|
||||
}
|
||||
|
||||
message GetDimensionsResponse {
|
||||
Dimensions dimensions = 1;
|
||||
}
|
||||
|
||||
message GetVisibleRegionRequest {
|
||||
string canvas_id = 1;
|
||||
}
|
||||
|
||||
message GetVisibleRegionResponse {
|
||||
VisibleRegion region = 1;
|
||||
}
|
||||
|
||||
message IsTileVisibleRequest {
|
||||
string canvas_id = 1;
|
||||
int32 x = 2;
|
||||
int32 y = 3;
|
||||
}
|
||||
|
||||
message IsTileVisibleResponse {
|
||||
bool is_visible = 1;
|
||||
}
|
||||
|
||||
366
src/protos/emulator_service.proto
Normal file
366
src/protos/emulator_service.proto
Normal file
@@ -0,0 +1,366 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package yaze.agent;
|
||||
|
||||
// The main service for controlling the yaze emulator
|
||||
service EmulatorService {
|
||||
// --- Lifecycle ---
|
||||
rpc Start(Empty) returns (CommandResponse);
|
||||
rpc Stop(Empty) returns (CommandResponse);
|
||||
rpc Pause(Empty) returns (CommandResponse);
|
||||
rpc Resume(Empty) returns (CommandResponse);
|
||||
rpc Reset(Empty) returns (CommandResponse);
|
||||
|
||||
// --- Input Control ---
|
||||
rpc PressButtons(ButtonRequest) returns (CommandResponse);
|
||||
rpc ReleaseButtons(ButtonRequest) returns (CommandResponse);
|
||||
rpc HoldButtons(ButtonHoldRequest) returns (CommandResponse);
|
||||
|
||||
// --- State Inspection (The Feedback Loop) ---
|
||||
rpc GetGameState(GameStateRequest) returns (GameStateResponse);
|
||||
rpc ReadMemory(MemoryRequest) returns (MemoryResponse);
|
||||
rpc WriteMemory(MemoryWriteRequest) returns (CommandResponse);
|
||||
|
||||
// --- Advanced Debugging (NEW) ---
|
||||
// Breakpoints
|
||||
rpc AddBreakpoint(BreakpointRequest) returns (BreakpointResponse);
|
||||
rpc RemoveBreakpoint(BreakpointIdRequest) returns (CommandResponse);
|
||||
rpc ListBreakpoints(Empty) returns (BreakpointListResponse);
|
||||
rpc SetBreakpointEnabled(BreakpointStateRequest) returns (CommandResponse);
|
||||
|
||||
// Watchpoints (memory access tracking)
|
||||
rpc AddWatchpoint(WatchpointRequest) returns (WatchpointResponse);
|
||||
rpc RemoveWatchpoint(WatchpointIdRequest) returns (CommandResponse);
|
||||
rpc ListWatchpoints(Empty) returns (WatchpointListResponse);
|
||||
rpc GetWatchpointHistory(WatchpointHistoryRequest) returns (WatchpointHistoryResponse);
|
||||
|
||||
// Execution Control
|
||||
rpc StepInstruction(Empty) returns (StepResponse);
|
||||
rpc RunToBreakpoint(Empty) returns (BreakpointHitResponse);
|
||||
rpc StepOver(Empty) returns (StepResponse); // Step over subroutines
|
||||
rpc StepOut(Empty) returns (StepResponse); // Step out of subroutine
|
||||
|
||||
// Disassembly & Code Analysis
|
||||
rpc GetDisassembly(DisassemblyRequest) returns (DisassemblyResponse);
|
||||
rpc GetExecutionTrace(TraceRequest) returns (TraceResponse);
|
||||
|
||||
// Symbol Management (for Oracle of Secrets labels)
|
||||
rpc LoadSymbols(SymbolFileRequest) returns (CommandResponse);
|
||||
rpc ResolveSymbol(SymbolLookupRequest) returns (SymbolLookupResponse);
|
||||
rpc GetSymbolAt(AddressRequest) returns (SymbolLookupResponse);
|
||||
|
||||
// Debugging Session
|
||||
rpc CreateDebugSession(DebugSessionRequest) returns (DebugSessionResponse);
|
||||
rpc GetDebugStatus(Empty) returns (DebugStatusResponse);
|
||||
}
|
||||
|
||||
// --- Message Definitions ---
|
||||
|
||||
message Empty {}
|
||||
|
||||
message CommandResponse {
|
||||
bool success = 1;
|
||||
string message = 2;
|
||||
}
|
||||
|
||||
enum Button {
|
||||
BUTTON_UNSPECIFIED = 0;
|
||||
A = 1;
|
||||
B = 2;
|
||||
X = 3;
|
||||
Y = 4;
|
||||
L = 5;
|
||||
R = 6;
|
||||
SELECT = 7;
|
||||
START = 8;
|
||||
UP = 9;
|
||||
DOWN = 10;
|
||||
LEFT = 11;
|
||||
RIGHT = 12;
|
||||
}
|
||||
|
||||
message ButtonRequest {
|
||||
repeated Button buttons = 1;
|
||||
}
|
||||
|
||||
message ButtonHoldRequest {
|
||||
repeated Button buttons = 1;
|
||||
uint32 duration_ms = 2; // How long to hold the buttons
|
||||
}
|
||||
|
||||
message GameStateRequest {
|
||||
bool include_screenshot = 1;
|
||||
repeated MemoryRequest memory_reads = 2;
|
||||
}
|
||||
|
||||
message GameStateResponse {
|
||||
// Key player and game variables
|
||||
uint32 game_mode = 1;
|
||||
uint32 link_state = 2;
|
||||
uint32 link_pos_x = 3;
|
||||
uint32 link_pos_y = 4;
|
||||
uint32 link_health = 5;
|
||||
|
||||
// Screenshot of the current frame
|
||||
bytes screenshot_png = 6; // PNG encoded image data
|
||||
|
||||
// Results of any requested memory reads
|
||||
repeated MemoryResponse memory_responses = 7;
|
||||
}
|
||||
|
||||
message MemoryRequest {
|
||||
uint32 address = 1;
|
||||
uint32 size = 2;
|
||||
}
|
||||
|
||||
message MemoryResponse {
|
||||
uint32 address = 1;
|
||||
bytes data = 2;
|
||||
}
|
||||
|
||||
message MemoryWriteRequest {
|
||||
uint32 address = 1;
|
||||
bytes data = 2;
|
||||
}
|
||||
|
||||
// --- Advanced Debugging Messages (NEW) ---
|
||||
|
||||
// Breakpoint types (matches BreakpointManager::Type)
|
||||
enum BreakpointType {
|
||||
BREAKPOINT_TYPE_UNSPECIFIED = 0;
|
||||
EXECUTE = 1; // Break when PC reaches address
|
||||
READ = 2; // Break when memory is read
|
||||
WRITE = 3; // Break when memory is written
|
||||
ACCESS = 4; // Break on read OR write
|
||||
CONDITIONAL = 5; // Break when condition is true
|
||||
}
|
||||
|
||||
// CPU type for breakpoints
|
||||
enum CpuType {
|
||||
CPU_TYPE_UNSPECIFIED = 0;
|
||||
CPU_65816 = 1;
|
||||
SPC700 = 2;
|
||||
}
|
||||
|
||||
// Breakpoint request
|
||||
message BreakpointRequest {
|
||||
uint32 address = 1;
|
||||
BreakpointType type = 2;
|
||||
CpuType cpu = 3;
|
||||
string condition = 4; // Optional condition (e.g., "A > 0x10")
|
||||
string description = 5; // User-friendly label
|
||||
}
|
||||
|
||||
message BreakpointResponse {
|
||||
bool success = 1;
|
||||
uint32 breakpoint_id = 2;
|
||||
string message = 3;
|
||||
}
|
||||
|
||||
message BreakpointIdRequest {
|
||||
uint32 breakpoint_id = 1;
|
||||
}
|
||||
|
||||
message BreakpointStateRequest {
|
||||
uint32 breakpoint_id = 1;
|
||||
bool enabled = 2;
|
||||
}
|
||||
|
||||
message BreakpointInfo {
|
||||
uint32 id = 1;
|
||||
uint32 address = 2;
|
||||
BreakpointType type = 3;
|
||||
CpuType cpu = 4;
|
||||
bool enabled = 5;
|
||||
string condition = 6;
|
||||
string description = 7;
|
||||
uint32 hit_count = 8;
|
||||
}
|
||||
|
||||
message BreakpointListResponse {
|
||||
repeated BreakpointInfo breakpoints = 1;
|
||||
}
|
||||
|
||||
message BreakpointHitResponse {
|
||||
bool hit = 1;
|
||||
BreakpointInfo breakpoint = 2;
|
||||
CPUState cpu_state = 3;
|
||||
string message = 4;
|
||||
}
|
||||
|
||||
// Watchpoint messages
|
||||
message WatchpointRequest {
|
||||
uint32 start_address = 1;
|
||||
uint32 end_address = 2; // For range watchpoints
|
||||
bool track_reads = 3;
|
||||
bool track_writes = 4;
|
||||
bool break_on_access = 5;
|
||||
string description = 6;
|
||||
}
|
||||
|
||||
message WatchpointResponse {
|
||||
bool success = 1;
|
||||
uint32 watchpoint_id = 2;
|
||||
string message = 3;
|
||||
}
|
||||
|
||||
message WatchpointIdRequest {
|
||||
uint32 watchpoint_id = 1;
|
||||
}
|
||||
|
||||
message WatchpointInfo {
|
||||
uint32 id = 1;
|
||||
uint32 start_address = 2;
|
||||
uint32 end_address = 3;
|
||||
bool track_reads = 4;
|
||||
bool track_writes = 5;
|
||||
bool break_on_access = 6;
|
||||
bool enabled = 7;
|
||||
string description = 8;
|
||||
}
|
||||
|
||||
message WatchpointListResponse {
|
||||
repeated WatchpointInfo watchpoints = 1;
|
||||
}
|
||||
|
||||
message WatchpointHistoryRequest {
|
||||
uint32 watchpoint_id = 1;
|
||||
uint32 max_entries = 2; // Max history entries to return
|
||||
}
|
||||
|
||||
message AccessLogEntry {
|
||||
uint32 pc = 1;
|
||||
uint32 address = 2;
|
||||
uint32 old_value = 3;
|
||||
uint32 new_value = 4;
|
||||
bool is_write = 5;
|
||||
uint64 cycle_count = 6;
|
||||
string description = 7;
|
||||
}
|
||||
|
||||
message WatchpointHistoryResponse {
|
||||
repeated AccessLogEntry history = 1;
|
||||
}
|
||||
|
||||
// CPU State (for stepping/debugging)
|
||||
message CPUState {
|
||||
uint32 a = 1;
|
||||
uint32 x = 2;
|
||||
uint32 y = 3;
|
||||
uint32 sp = 4;
|
||||
uint32 pc = 5;
|
||||
uint32 db = 6; // Data bank
|
||||
uint32 pb = 7; // Program bank
|
||||
uint32 d = 8; // Direct page
|
||||
uint32 status = 9; // Processor status
|
||||
bool flag_n = 10; // Negative
|
||||
bool flag_v = 11; // Overflow
|
||||
bool flag_d = 12; // Decimal
|
||||
bool flag_i = 13; // Interrupt disable
|
||||
bool flag_z = 14; // Zero
|
||||
bool flag_c = 15; // Carry
|
||||
uint64 cycles = 16;
|
||||
}
|
||||
|
||||
message StepResponse {
|
||||
bool success = 1;
|
||||
CPUState cpu_state = 2;
|
||||
DisassemblyLine instruction = 3;
|
||||
string message = 4;
|
||||
}
|
||||
|
||||
// Disassembly messages
|
||||
message DisassemblyRequest {
|
||||
uint32 start_address = 1;
|
||||
uint32 count = 2; // Number of instructions
|
||||
bool include_execution_count = 3;
|
||||
}
|
||||
|
||||
message DisassemblyLine {
|
||||
uint32 address = 1;
|
||||
uint32 opcode = 2;
|
||||
repeated uint32 operands = 3;
|
||||
string mnemonic = 4;
|
||||
string operand_str = 5;
|
||||
uint32 size = 6;
|
||||
uint64 execution_count = 7;
|
||||
bool is_breakpoint = 8;
|
||||
}
|
||||
|
||||
message DisassemblyResponse {
|
||||
repeated DisassemblyLine lines = 1;
|
||||
}
|
||||
|
||||
// Execution trace
|
||||
message TraceRequest {
|
||||
uint32 max_entries = 1; // Max trace entries to return
|
||||
uint32 start_address = 2; // Optional: filter by address range
|
||||
uint32 end_address = 3;
|
||||
}
|
||||
|
||||
message TraceEntry {
|
||||
uint32 address = 1;
|
||||
string instruction = 2;
|
||||
CPUState cpu_state_before = 3;
|
||||
uint64 cycle_count = 4;
|
||||
}
|
||||
|
||||
message TraceResponse {
|
||||
repeated TraceEntry entries = 1;
|
||||
uint32 total_count = 2;
|
||||
}
|
||||
|
||||
// Symbol management
|
||||
message SymbolFileRequest {
|
||||
string filepath = 1; // Path to symbol file (e.g., .sym, .map)
|
||||
SymbolFormat format = 2;
|
||||
}
|
||||
|
||||
enum SymbolFormat {
|
||||
SYMBOL_FORMAT_UNSPECIFIED = 0;
|
||||
ASAR = 1; // Asar assembler format
|
||||
WLA_DX = 2; // WLA-DX assembler format
|
||||
CA65 = 3; // ca65 assembler format
|
||||
MESEN = 4; // Mesen debug symbol format
|
||||
CUSTOM_JSON = 5; // Custom JSON format
|
||||
}
|
||||
|
||||
message SymbolLookupRequest {
|
||||
string symbol_name = 1;
|
||||
}
|
||||
|
||||
message AddressRequest {
|
||||
uint32 address = 1;
|
||||
}
|
||||
|
||||
message SymbolLookupResponse {
|
||||
bool found = 1;
|
||||
string symbol_name = 2;
|
||||
uint32 address = 3;
|
||||
string type = 4; // "function", "data", "label", etc.
|
||||
string description = 5;
|
||||
}
|
||||
|
||||
// Debug session
|
||||
message DebugSessionRequest {
|
||||
string session_name = 1;
|
||||
string rom_hash = 2; // For verification
|
||||
bool enable_all_features = 3;
|
||||
}
|
||||
|
||||
message DebugSessionResponse {
|
||||
bool success = 1;
|
||||
string session_id = 2;
|
||||
string message = 3;
|
||||
}
|
||||
|
||||
message DebugStatusResponse {
|
||||
bool is_running = 1;
|
||||
bool is_paused = 2;
|
||||
CPUState cpu_state = 3;
|
||||
uint32 active_breakpoints = 4;
|
||||
uint32 active_watchpoints = 5;
|
||||
BreakpointInfo last_breakpoint_hit = 6;
|
||||
double fps = 7;
|
||||
uint64 cycles = 8;
|
||||
}
|
||||
356
src/protos/imgui_test_harness.proto
Normal file
356
src/protos/imgui_test_harness.proto
Normal file
@@ -0,0 +1,356 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package yaze.test;
|
||||
|
||||
// ImGuiTestHarness service for remote GUI testing
|
||||
// Allows z3ed CLI to interact with YAZE's GUI for automated testing
|
||||
service ImGuiTestHarness {
|
||||
// Health check - verifies the service is running
|
||||
rpc Ping(PingRequest) returns (PingResponse);
|
||||
|
||||
// Click a button or interactive element
|
||||
rpc Click(ClickRequest) returns (ClickResponse);
|
||||
|
||||
// Type text into an input field
|
||||
rpc Type(TypeRequest) returns (TypeResponse);
|
||||
|
||||
// Wait for a condition to be true
|
||||
rpc Wait(WaitRequest) returns (WaitResponse);
|
||||
|
||||
// Assert that a condition is true
|
||||
rpc Assert(AssertRequest) returns (AssertResponse);
|
||||
|
||||
// Capture a screenshot
|
||||
rpc Screenshot(ScreenshotRequest) returns (ScreenshotResponse);
|
||||
|
||||
// Test introspection APIs (IT-05)
|
||||
rpc GetTestStatus(GetTestStatusRequest) returns (GetTestStatusResponse);
|
||||
rpc ListTests(ListTestsRequest) returns (ListTestsResponse);
|
||||
rpc GetTestResults(GetTestResultsRequest) returns (GetTestResultsResponse);
|
||||
|
||||
// Widget discovery API (IT-06)
|
||||
rpc DiscoverWidgets(DiscoverWidgetsRequest) returns (DiscoverWidgetsResponse);
|
||||
|
||||
// Test recording & replay (IT-07)
|
||||
rpc StartRecording(StartRecordingRequest) returns (StartRecordingResponse);
|
||||
rpc StopRecording(StopRecordingRequest) returns (StopRecordingResponse);
|
||||
rpc ReplayTest(ReplayTestRequest) returns (ReplayTestResponse);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Ping - Health Check
|
||||
// ============================================================================
|
||||
|
||||
message PingRequest {
|
||||
string message = 1; // Message to echo back
|
||||
}
|
||||
|
||||
message PingResponse {
|
||||
string message = 1; // Echoed message with "Pong: " prefix
|
||||
int64 timestamp_ms = 2; // Server timestamp in milliseconds
|
||||
string yaze_version = 3; // YAZE version string (e.g., "0.3.2")
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Click - Interact with GUI elements
|
||||
// ============================================================================
|
||||
|
||||
message ClickRequest {
|
||||
string target = 1; // Target element (e.g., "button:Open ROM")
|
||||
ClickType type = 2; // Type of click
|
||||
|
||||
enum ClickType {
|
||||
CLICK_TYPE_UNSPECIFIED = 0; // Default/unspecified click type
|
||||
CLICK_TYPE_LEFT = 1; // Single left click
|
||||
CLICK_TYPE_RIGHT = 2; // Single right click
|
||||
CLICK_TYPE_DOUBLE = 3; // Double click
|
||||
CLICK_TYPE_MIDDLE = 4; // Middle mouse button
|
||||
}
|
||||
}
|
||||
|
||||
message ClickResponse {
|
||||
bool success = 1; // Whether the click succeeded
|
||||
string message = 2; // Human-readable result message
|
||||
int32 execution_time_ms = 3; // Time taken to execute (for debugging)
|
||||
string test_id = 4; // Unique test identifier for introspection
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Type - Send keyboard input
|
||||
// ============================================================================
|
||||
|
||||
message TypeRequest {
|
||||
string target = 1; // Target input field (e.g., "textbox:File Path")
|
||||
string text = 2; // Text to type
|
||||
bool clear_first = 3; // Clear existing text before typing
|
||||
}
|
||||
|
||||
message TypeResponse {
|
||||
bool success = 1;
|
||||
string message = 2;
|
||||
int32 execution_time_ms = 3;
|
||||
string test_id = 4;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Wait - Poll for conditions
|
||||
// ============================================================================
|
||||
|
||||
message WaitRequest {
|
||||
string condition = 1; // Condition to wait for (e.g., "window:Overworld")
|
||||
int32 timeout_ms = 2; // Maximum time to wait (default 5000ms)
|
||||
int32 poll_interval_ms = 3; // How often to check (default 100ms)
|
||||
}
|
||||
|
||||
message WaitResponse {
|
||||
bool success = 1; // Whether condition was met before timeout
|
||||
string message = 2;
|
||||
int32 elapsed_ms = 3; // Time taken before condition met (or timeout)
|
||||
string test_id = 4; // Unique test identifier for introspection
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Assert - Validate GUI state
|
||||
// ============================================================================
|
||||
|
||||
message AssertRequest {
|
||||
string condition = 1; // Condition to assert (e.g., "visible:button:Save")
|
||||
string failure_message = 2; // Custom message if assertion fails
|
||||
}
|
||||
|
||||
message AssertResponse {
|
||||
bool success = 1; // Whether assertion passed
|
||||
string message = 2; // Diagnostic message
|
||||
string actual_value = 3; // Actual value found (for debugging)
|
||||
string expected_value = 4; // Expected value (for debugging)
|
||||
string test_id = 5; // Unique test identifier for introspection
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Screenshot - Capture window state
|
||||
// ============================================================================
|
||||
|
||||
message ScreenshotRequest {
|
||||
string window_title = 1; // Window to capture (empty = main window)
|
||||
string output_path = 2; // Where to save screenshot
|
||||
ImageFormat format = 3; // Image format
|
||||
|
||||
enum ImageFormat {
|
||||
IMAGE_FORMAT_UNSPECIFIED = 0;
|
||||
IMAGE_FORMAT_PNG = 1;
|
||||
IMAGE_FORMAT_JPEG = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message ScreenshotResponse {
|
||||
bool success = 1;
|
||||
string message = 2;
|
||||
string file_path = 3; // Absolute path to saved screenshot
|
||||
int64 file_size_bytes = 4;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// GetTestStatus - Query test execution state
|
||||
// ============================================================================
|
||||
|
||||
message GetTestStatusRequest {
|
||||
string test_id = 1; // Test ID from Click/Type/Wait/Assert response
|
||||
}
|
||||
|
||||
message GetTestStatusResponse {
|
||||
enum TestStatus {
|
||||
TEST_STATUS_UNSPECIFIED = 0; // Test ID not found or unspecified
|
||||
TEST_STATUS_QUEUED = 1; // Waiting to execute
|
||||
TEST_STATUS_RUNNING = 2; // Currently executing
|
||||
TEST_STATUS_PASSED = 3; // Completed successfully
|
||||
TEST_STATUS_FAILED = 4; // Assertion failed or error
|
||||
TEST_STATUS_TIMEOUT = 5; // Exceeded timeout
|
||||
}
|
||||
|
||||
TestStatus status = 1;
|
||||
int64 queued_at_ms = 2; // When test was queued
|
||||
int64 started_at_ms = 3; // When test started (0 if not started)
|
||||
int64 completed_at_ms = 4; // When test completed (0 if not complete)
|
||||
int32 execution_time_ms = 5; // Total execution time
|
||||
string error_message = 6; // Error details if FAILED/TIMEOUT
|
||||
repeated string assertion_failures = 7; // Failed assertion details
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ListTests - Enumerate available tests
|
||||
// ============================================================================
|
||||
|
||||
message ListTestsRequest {
|
||||
string category_filter = 1; // Optional: "grpc", "unit", "integration", "e2e"
|
||||
int32 page_size = 2; // Number of results per page (default 100)
|
||||
string page_token = 3; // Pagination token from previous response
|
||||
}
|
||||
|
||||
message ListTestsResponse {
|
||||
repeated TestInfo tests = 1;
|
||||
string next_page_token = 2; // Token for next page (empty if no more)
|
||||
int32 total_count = 3; // Total number of matching tests
|
||||
}
|
||||
|
||||
message TestInfo {
|
||||
string test_id = 1; // Unique test identifier
|
||||
string name = 2; // Human-readable test name
|
||||
string category = 3; // Category: grpc, unit, integration, e2e
|
||||
int64 last_run_timestamp_ms = 4; // When test last executed
|
||||
int32 total_runs = 5; // Total number of executions
|
||||
int32 pass_count = 6; // Number of successful runs
|
||||
int32 fail_count = 7; // Number of failed runs
|
||||
int32 average_duration_ms = 8; // Average execution time
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// GetTestResults - Retrieve detailed results
|
||||
// ============================================================================
|
||||
|
||||
message GetTestResultsRequest {
|
||||
string test_id = 1;
|
||||
bool include_logs = 2; // Include full execution logs
|
||||
}
|
||||
|
||||
message GetTestResultsResponse {
|
||||
bool success = 1; // Overall test result
|
||||
string test_name = 2;
|
||||
string category = 3;
|
||||
int64 executed_at_ms = 4;
|
||||
int32 duration_ms = 5;
|
||||
repeated AssertionResult assertions = 6;
|
||||
repeated string logs = 7; // If include_logs=true
|
||||
map<string, int32> metrics = 8; // e.g., "frame_count": 123
|
||||
|
||||
// IT-08b: Failure diagnostics
|
||||
string screenshot_path = 9; // Path to failure screenshot (if captured)
|
||||
int64 screenshot_size_bytes = 10; // Size of screenshot file
|
||||
string failure_context = 11; // Execution context at failure time
|
||||
string widget_state = 12; // Widget state dump (IT-08c - future)
|
||||
}
|
||||
|
||||
message AssertionResult {
|
||||
string description = 1;
|
||||
bool passed = 2;
|
||||
string expected_value = 3;
|
||||
string actual_value = 4;
|
||||
string error_message = 5;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// DiscoverWidgets - Enumerate discoverable GUI widgets
|
||||
// ============================================================================
|
||||
|
||||
message DiscoverWidgetsRequest {
|
||||
// Optional: Limit to a window name (case-insensitive)
|
||||
string window_filter = 1;
|
||||
// Optional: Limit to widget type
|
||||
WidgetType type_filter = 2;
|
||||
// Optional: Require widget path to start with prefix
|
||||
string path_prefix = 3;
|
||||
// Include widgets that are currently not visible
|
||||
bool include_invisible = 4;
|
||||
// Include widgets that are currently disabled
|
||||
bool include_disabled = 5;
|
||||
}
|
||||
|
||||
enum WidgetType {
|
||||
WIDGET_TYPE_UNSPECIFIED = 0;
|
||||
WIDGET_TYPE_ALL = 1;
|
||||
WIDGET_TYPE_BUTTON = 2;
|
||||
WIDGET_TYPE_INPUT = 3;
|
||||
WIDGET_TYPE_MENU = 4;
|
||||
WIDGET_TYPE_TAB = 5;
|
||||
WIDGET_TYPE_CHECKBOX = 6;
|
||||
WIDGET_TYPE_SLIDER = 7;
|
||||
WIDGET_TYPE_CANVAS = 8;
|
||||
WIDGET_TYPE_SELECTABLE = 9;
|
||||
WIDGET_TYPE_OTHER = 10;
|
||||
}
|
||||
|
||||
message WidgetBounds {
|
||||
float min_x = 1;
|
||||
float min_y = 2;
|
||||
float max_x = 3;
|
||||
float max_y = 4;
|
||||
}
|
||||
|
||||
message DiscoveredWidget {
|
||||
// Full hierarchical path (e.g. Overworld/Toolset/button:Pan)
|
||||
string path = 1;
|
||||
// Human-readable label (e.g. Pan)
|
||||
string label = 2;
|
||||
// Widget type string (button, input, ...)
|
||||
string type = 3;
|
||||
// Description provided by registry (if any)
|
||||
string description = 4;
|
||||
// Suggested action for automation (e.g. "Click button:Pan")
|
||||
string suggested_action = 5;
|
||||
bool visible = 6; // Currently visible in UI
|
||||
bool enabled = 7; // Currently enabled for interaction
|
||||
WidgetBounds bounds = 8; // Bounding rectangle in screen coordinates
|
||||
uint32 widget_id = 9; // ImGui ID (debugging / direct access)
|
||||
int64 last_seen_frame = 10; // Frame number when widget was last observed
|
||||
int64 last_seen_at_ms = 11; // Wall-clock timestamp of last observation
|
||||
bool stale = 12; // True if widget not seen in the current frame
|
||||
}
|
||||
|
||||
message DiscoveredWindow {
|
||||
// Window name (first segment of path)
|
||||
string name = 1;
|
||||
// Whether the window is currently visible
|
||||
bool visible = 2;
|
||||
// Widgets contained in this window
|
||||
repeated DiscoveredWidget widgets = 3;
|
||||
}
|
||||
|
||||
message DiscoverWidgetsResponse {
|
||||
repeated DiscoveredWindow windows = 1;
|
||||
int32 total_widgets = 2; // Total number of widgets returned
|
||||
int64 generated_at_ms = 3; // Snapshot timestamp (Unix ms)
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Test Recording & Replay (IT-07)
|
||||
// ============================================================================
|
||||
|
||||
message StartRecordingRequest {
|
||||
string output_path = 1; // Where to store the JSON script
|
||||
string session_name = 2; // Optional friendly name for the recording
|
||||
string description = 3; // Optional description stored alongside metadata
|
||||
}
|
||||
|
||||
message StartRecordingResponse {
|
||||
bool success = 1;
|
||||
string message = 2;
|
||||
string recording_id = 3; // Identifier required when stopping
|
||||
int64 started_at_ms = 4;
|
||||
}
|
||||
|
||||
message StopRecordingRequest {
|
||||
string recording_id = 1; // Recording session to stop
|
||||
bool discard = 2; // If true, delete steps instead of writing file
|
||||
}
|
||||
|
||||
message StopRecordingResponse {
|
||||
bool success = 1;
|
||||
string message = 2;
|
||||
string output_path = 3; // Final location of saved script (if any)
|
||||
int32 step_count = 4; // Total steps captured during session
|
||||
int64 duration_ms = 5; // Duration of the recording session
|
||||
}
|
||||
|
||||
message ReplayTestRequest {
|
||||
string script_path = 1; // Path to JSON script
|
||||
bool ci_mode = 2; // Suppress interactive prompts
|
||||
map<string, string> parameter_overrides = 3; // Optional parameter overrides
|
||||
}
|
||||
|
||||
message ReplayTestResponse {
|
||||
bool success = 1;
|
||||
string message = 2;
|
||||
string replay_session_id = 3;
|
||||
int32 steps_executed = 4;
|
||||
repeated AssertionResult assertions = 5; // Aggregated assertion outcomes
|
||||
repeated string logs = 6; // Replay log entries
|
||||
}
|
||||
223
src/protos/rom_service.proto
Normal file
223
src/protos/rom_service.proto
Normal file
@@ -0,0 +1,223 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package yaze.proto;
|
||||
|
||||
// ROM Manipulation Service
|
||||
// Enables remote clients to read, write, and inspect ROM data
|
||||
service RomService {
|
||||
// Read bytes from ROM
|
||||
rpc ReadBytes(ReadBytesRequest) returns (ReadBytesResponse);
|
||||
|
||||
// Write bytes to ROM
|
||||
rpc WriteBytes(WriteBytesRequest) returns (WriteBytesResponse);
|
||||
|
||||
// Get ROM information
|
||||
rpc GetRomInfo(GetRomInfoRequest) returns (GetRomInfoResponse);
|
||||
|
||||
// Read specific ROM structures
|
||||
rpc ReadOverworldMap(ReadOverworldMapRequest) returns (ReadOverworldMapResponse);
|
||||
rpc ReadDungeonRoom(ReadDungeonRoomRequest) returns (ReadDungeonRoomResponse);
|
||||
rpc ReadSprite(ReadSpriteRequest) returns (ReadSpriteResponse);
|
||||
|
||||
// Write specific ROM structures
|
||||
rpc WriteOverworldTile(WriteOverworldTileRequest) returns (WriteOverworldTileResponse);
|
||||
rpc WriteDungeonTile(WriteDungeonTileRequest) returns (WriteDungeonTileResponse);
|
||||
|
||||
// Proposal-based changes (collaborative mode)
|
||||
rpc SubmitRomProposal(SubmitRomProposalRequest) returns (SubmitRomProposalResponse);
|
||||
rpc GetProposalStatus(GetProposalStatusRequest) returns (GetProposalStatusResponse);
|
||||
|
||||
// Version management
|
||||
rpc CreateSnapshot(CreateSnapshotRequest) returns (CreateSnapshotResponse);
|
||||
rpc RestoreSnapshot(RestoreSnapshotRequest) returns (RestoreSnapshotResponse);
|
||||
rpc ListSnapshots(ListSnapshotsRequest) returns (ListSnapshotsResponse);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Basic ROM Operations
|
||||
// ============================================================================
|
||||
|
||||
message ReadBytesRequest {
|
||||
uint32 offset = 1;
|
||||
uint32 length = 2;
|
||||
}
|
||||
|
||||
message ReadBytesResponse {
|
||||
bytes data = 1;
|
||||
string error = 2;
|
||||
}
|
||||
|
||||
message WriteBytesRequest {
|
||||
uint32 offset = 1;
|
||||
bytes data = 2;
|
||||
bool require_approval = 3; // Submit as proposal if true
|
||||
}
|
||||
|
||||
message WriteBytesResponse {
|
||||
bool success = 1;
|
||||
string error = 2;
|
||||
string proposal_id = 3; // Set if submitted as proposal
|
||||
}
|
||||
|
||||
message GetRomInfoRequest {
|
||||
// Empty for now
|
||||
}
|
||||
|
||||
message GetRomInfoResponse {
|
||||
string title = 1;
|
||||
uint32 size = 2;
|
||||
string checksum = 3;
|
||||
bool is_expanded = 4;
|
||||
string version = 5;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Overworld Operations
|
||||
// ============================================================================
|
||||
|
||||
message ReadOverworldMapRequest {
|
||||
uint32 map_id = 1; // 0-159
|
||||
}
|
||||
|
||||
message ReadOverworldMapResponse {
|
||||
uint32 map_id = 1;
|
||||
repeated uint32 tile16_data = 2; // 512 tiles (32x16)
|
||||
bytes raw_data = 3;
|
||||
string error = 4;
|
||||
}
|
||||
|
||||
message WriteOverworldTileRequest {
|
||||
uint32 map_id = 1;
|
||||
uint32 x = 2;
|
||||
uint32 y = 3;
|
||||
uint32 tile16_id = 4;
|
||||
bool require_approval = 5;
|
||||
string description = 6; // For proposal description
|
||||
}
|
||||
|
||||
message WriteOverworldTileResponse {
|
||||
bool success = 1;
|
||||
string error = 2;
|
||||
string proposal_id = 3;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Dungeon Operations
|
||||
// ============================================================================
|
||||
|
||||
message ReadDungeonRoomRequest {
|
||||
uint32 room_id = 1; // 0-295
|
||||
}
|
||||
|
||||
message ReadDungeonRoomResponse {
|
||||
uint32 room_id = 1;
|
||||
repeated uint32 tile16_data = 2;
|
||||
bytes raw_data = 3;
|
||||
string error = 4;
|
||||
}
|
||||
|
||||
message WriteDungeonTileRequest {
|
||||
uint32 room_id = 1;
|
||||
uint32 x = 2;
|
||||
uint32 y = 3;
|
||||
uint32 tile16_id = 4;
|
||||
bool require_approval = 5;
|
||||
string description = 6;
|
||||
}
|
||||
|
||||
message WriteDungeonTileResponse {
|
||||
bool success = 1;
|
||||
string error = 2;
|
||||
string proposal_id = 3;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Sprite Operations
|
||||
// ============================================================================
|
||||
|
||||
message ReadSpriteRequest {
|
||||
uint32 sprite_id = 1;
|
||||
}
|
||||
|
||||
message ReadSpriteResponse {
|
||||
uint32 sprite_id = 1;
|
||||
bytes sprite_data = 2;
|
||||
string error = 3;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Proposal System
|
||||
// ============================================================================
|
||||
|
||||
message SubmitRomProposalRequest {
|
||||
string description = 1;
|
||||
string username = 2;
|
||||
|
||||
oneof proposal_type {
|
||||
WriteBytesRequest write_bytes = 3;
|
||||
WriteOverworldTileRequest overworld_tile = 4;
|
||||
WriteDungeonTileRequest dungeon_tile = 5;
|
||||
}
|
||||
}
|
||||
|
||||
message SubmitRomProposalResponse {
|
||||
bool success = 1;
|
||||
string proposal_id = 2;
|
||||
string error = 3;
|
||||
}
|
||||
|
||||
message GetProposalStatusRequest {
|
||||
string proposal_id = 1;
|
||||
}
|
||||
|
||||
message GetProposalStatusResponse {
|
||||
string proposal_id = 1;
|
||||
string status = 2; // pending, approved, rejected, applied
|
||||
repeated string voters = 3;
|
||||
int32 approval_count = 4;
|
||||
int32 rejection_count = 5;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Version Management
|
||||
// ============================================================================
|
||||
|
||||
message CreateSnapshotRequest {
|
||||
string description = 1;
|
||||
string username = 2;
|
||||
bool is_checkpoint = 3;
|
||||
}
|
||||
|
||||
message CreateSnapshotResponse {
|
||||
bool success = 1;
|
||||
string snapshot_id = 2;
|
||||
string error = 3;
|
||||
}
|
||||
|
||||
message RestoreSnapshotRequest {
|
||||
string snapshot_id = 1;
|
||||
}
|
||||
|
||||
message RestoreSnapshotResponse {
|
||||
bool success = 1;
|
||||
string error = 2;
|
||||
}
|
||||
|
||||
message ListSnapshotsRequest {
|
||||
uint32 max_results = 1; // 0 = all
|
||||
}
|
||||
|
||||
message SnapshotInfo {
|
||||
string snapshot_id = 1;
|
||||
string description = 2;
|
||||
string username = 3;
|
||||
int64 timestamp = 4;
|
||||
bool is_checkpoint = 5;
|
||||
bool is_safe_point = 6;
|
||||
uint64 size_bytes = 7;
|
||||
}
|
||||
|
||||
message ListSnapshotsResponse {
|
||||
repeated SnapshotInfo snapshots = 1;
|
||||
string error = 2;
|
||||
}
|
||||
Reference in New Issue
Block a user