From 5034e1e97d9e65bf65ba17b792ca09adfff8e339 Mon Sep 17 00:00:00 2001 From: scawful Date: Sun, 5 Oct 2025 12:16:59 -0400 Subject: [PATCH] feat: Add Common Tiles Reference and Enhance Asset Management - Introduced a new common_tiles.txt file for AI agents, providing a customizable reference for various tile types used in projects. - Updated CMake configuration to improve asset copying for macOS and non-Apple platforms, ensuring agent assets are correctly placed in the output directory. - Enhanced the AssetLoader to support additional search paths for asset retrieval, improving cross-platform compatibility. - Improved error handling in the AgentEditor for missing prompt files, providing clearer instructions for users on file locations and creation. --- assets/agent/common_tiles.txt | 42 ++++++++++++++++ src/app/app.cmake | 26 +++++++++- src/app/core/platform/asset_loader.cc | 11 ++++- src/app/editor/agent/agent_editor.cc | 34 +++++++++---- .../editor/system/agent_chat_history_popup.cc | 48 ++++++++----------- src/app/gui/style.cc | 2 +- src/app/gui/theme_manager.cc | 6 +-- 7 files changed, 125 insertions(+), 44 deletions(-) create mode 100644 assets/agent/common_tiles.txt diff --git a/assets/agent/common_tiles.txt b/assets/agent/common_tiles.txt new file mode 100644 index 00000000..3a4dabc6 --- /dev/null +++ b/assets/agent/common_tiles.txt @@ -0,0 +1,42 @@ +# Common Tile16 Reference for AI Agents +# This file can be customized per project + +[grass_tiles] +0x020 = Grass (standard) +0x021 = Grass variant 1 +0x0E0 = Grass (dark world) + +[nature_tiles] +0x02E = Tree (standard oak) +0x02F = Tree (palm) +0x003 = Bush (standard) +0x004 = Rock (standard) +0x021 = Flower (standard) + +[ground_tiles] +0x022 = Dirt (standard) +0x023 = Sand (desert) +0x024 = Stone path + +[water_tiles] +0x14C = Water (top edge) +0x14D = Water (middle) +0x14E = Water (bottom edge) +0x14F = Water (left edge) +0x150 = Water (right edge) + +[structure_tiles] +0x100 = Wall (castle, exterior) +0x101 = Wall (castle, interior) +0x120 = Door (standard) +0x121 = Door (locked) + +[special_tiles] +0x200 = Warp tile +0x201 = Treasure chest +0x202 = Switch tile + +# Notes: +# - IDs are in hexadecimal (0x prefix) +# - Customize this file for your ROM hack +# - AI will reference these when placing tiles diff --git a/src/app/app.cmake b/src/app/app.cmake index 506e5360..866fb687 100644 --- a/src/app/app.cmake +++ b/src/app/app.cmake @@ -178,8 +178,18 @@ if (APPLE) target_link_libraries(yaze PUBLIC ${COCOA_LIBRARY}) endif() -# Post-build step to copy assets to output directory (Windows/Linux) -if(NOT APPLE) +# Post-build step to copy assets to output directory +if(APPLE) + # macOS: Copy to bundle Resources + add_custom_command(TARGET yaze POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory + $/../Resources/agent + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_SOURCE_DIR}/assets/agent + $/../Resources/agent + COMMENT "Copying agent assets to macOS bundle" + ) +elseif(NOT APPLE) # Add post-build commands directly to the yaze target # Copy fonts add_custom_command(TARGET yaze POST_BUILD @@ -201,6 +211,18 @@ if(NOT APPLE) COMMENT "Copying theme assets" ) + # Copy agent assets (system prompts, etc.) + if(EXISTS ${CMAKE_SOURCE_DIR}/assets/agent) + add_custom_command(TARGET yaze POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory + $/assets/agent + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_SOURCE_DIR}/assets/agent + $/assets/agent + COMMENT "Copying agent assets (prompts, schemas)" + ) + endif() + # Copy other assets if they exist if(EXISTS ${CMAKE_SOURCE_DIR}/assets/layouts) add_custom_command(TARGET yaze POST_BUILD diff --git a/src/app/core/platform/asset_loader.cc b/src/app/core/platform/asset_loader.cc index 1cd30136..1c89d629 100644 --- a/src/app/core/platform/asset_loader.cc +++ b/src/app/core/platform/asset_loader.cc @@ -15,8 +15,16 @@ std::vector AssetLoader::GetSearchPaths(const std::string #ifdef __APPLE__ // macOS bundle resource paths std::string bundle_root = yaze::util::GetBundleResourcePath(); + + // Try Contents/Resources first (standard bundle location) search_paths.push_back(std::filesystem::path(bundle_root) / "Contents" / "Resources" / relative_path); - search_paths.push_back(std::filesystem::path(bundle_root) / "assets" / relative_path); + + // Try without Contents (if app is at root) + search_paths.push_back(std::filesystem::path(bundle_root) / "Resources" / relative_path); + + // Development paths (when running from build dir) + search_paths.push_back(std::filesystem::path(bundle_root) / ".." / ".." / ".." / "assets" / relative_path); + search_paths.push_back(std::filesystem::path(bundle_root) / ".." / ".." / ".." / ".." / "assets" / relative_path); #endif // Standard relative paths (works for all platforms) @@ -24,6 +32,7 @@ std::vector AssetLoader::GetSearchPaths(const std::string search_paths.push_back(std::filesystem::path("../assets") / relative_path); search_paths.push_back(std::filesystem::path("../../assets") / relative_path); search_paths.push_back(std::filesystem::path("../../../assets") / relative_path); + search_paths.push_back(std::filesystem::path("../../../../assets") / relative_path); // Build directory paths search_paths.push_back(std::filesystem::path("build/assets") / relative_path); diff --git a/src/app/editor/agent/agent_editor.cc b/src/app/editor/agent/agent_editor.cc index 6e8e49d6..4778cec9 100644 --- a/src/app/editor/agent/agent_editor.cc +++ b/src/app/editor/agent/agent_editor.cc @@ -534,18 +534,32 @@ void AgentEditor::DrawPromptEditorPanel() { prompt_editor_->SetText(*content_result); current_profile_.system_prompt = *content_result; prompt_editor_initialized_ = true; - } else { - // Only show error on first attempt (don't spam) - static bool error_shown = false; - if (!error_shown && toast_manager_) { + + if (toast_manager_) { toast_manager_->Show( - absl::StrFormat("Prompt file not found: %s", active_prompt_file_), - ToastType::kWarning, 3.0f); - error_shown = true; + absl::StrFormat(ICON_MD_CHECK_CIRCLE " Loaded %s", active_prompt_file_), + ToastType::kSuccess, 2.0f); } - // Set placeholder text - prompt_editor_->SetText("# System prompt file not found\n# Please check assets/agent/ directory"); - prompt_editor_initialized_ = true; // Don't retry every frame + } else { + // Show detailed error in console + std::cerr << "❌ Failed to load " << active_prompt_file_ << "\n"; + std::cerr << " Error: " << content_result.status().message() << "\n"; + + // Set placeholder with instructions + std::string placeholder = absl::StrFormat( + "# System prompt file not found: %s\n" + "# Error: %s\n\n" + "# Please ensure the file exists in:\n" + "# - assets/agent/%s\n" + "# - Or Contents/Resources/agent/%s (macOS bundle)\n\n" + "# You can create a custom prompt here and save it to your bot profile.", + active_prompt_file_, + content_result.status().message(), + active_prompt_file_, + active_prompt_file_); + + prompt_editor_->SetText(placeholder); + prompt_editor_initialized_ = true; } } diff --git a/src/app/editor/system/agent_chat_history_popup.cc b/src/app/editor/system/agent_chat_history_popup.cc index dc2ea380..d5f456b2 100644 --- a/src/app/editor/system/agent_chat_history_popup.cc +++ b/src/app/editor/system/agent_chat_history_popup.cc @@ -13,12 +13,13 @@ namespace editor { namespace { -const ImVec4 kUserColor = ImVec4(0.88f, 0.76f, 0.36f, 1.0f); -const ImVec4 kAgentColor = ImVec4(0.56f, 0.82f, 0.62f, 1.0f); -const ImVec4 kTimestampColor = ImVec4(0.6f, 0.6f, 0.6f, 1.0f); -const ImVec4 kAccentColor = ImVec4(0.196f, 0.6f, 0.8f, 1.0f); -const ImVec4 kBackgroundColor = ImVec4(0.08f, 0.08f, 0.12f, 0.98f); -const ImVec4 kHeaderColor = ImVec4(0.12f, 0.14f, 0.18f, 1.0f); +// Theme-matched colors +const ImVec4 kUserColor = ImVec4(0.90f, 0.70f, 0.00f, 1.0f); // Gold +const ImVec4 kAgentColor = ImVec4(0.40f, 0.76f, 0.64f, 1.0f); // Teal +const ImVec4 kTimestampColor = ImVec4(0.6f, 0.6f, 0.6f, 0.9f); +const ImVec4 kAccentColor = ImVec4(0.26f, 0.59f, 0.98f, 1.0f); // Theme blue +const ImVec4 kBackgroundColor = ImVec4(0.10f, 0.10f, 0.13f, 0.98f); // Darker +const ImVec4 kHeaderColor = ImVec4(0.14f, 0.14f, 0.16f, 1.0f); } // namespace @@ -40,11 +41,9 @@ void AgentChatHistoryPopup::Draw() { ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar; - // Beautiful gradient background - ImGui::PushStyleColor(ImGuiCol_WindowBg, kBackgroundColor); - ImGui::PushStyleColor(ImGuiCol_Border, kAccentColor); - ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 2.0f); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(12, 12)); + // Theme-matched styling + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10)); if (ImGui::Begin("##AgentChatPopup", &visible_, flags)) { // Animated header pulse @@ -85,7 +84,6 @@ void AgentChatHistoryPopup::Draw() { ImGui::End(); ImGui::PopStyleVar(2); - ImGui::PopStyleColor(2); } void AgentChatHistoryPopup::DrawMessageList() { @@ -161,34 +159,30 @@ void AgentChatHistoryPopup::DrawMessage(const cli::agent::ChatMessage& msg, int } void AgentChatHistoryPopup::DrawHeader() { - // Beautiful header with gradient accent + // Theme-matched header with subtle gradient ImDrawList* draw_list = ImGui::GetWindowDrawList(); ImVec2 header_start = ImGui::GetCursorScreenPos(); - ImVec2 header_size(ImGui::GetContentRegionAvail().x, 60); + ImVec2 header_size(ImGui::GetContentRegionAvail().x, 55); - // Gradient background - ImU32 color_top = ImGui::GetColorU32(ImVec4(0.15f, 0.18f, 0.22f, 1.0f)); - ImU32 color_bottom = ImGui::GetColorU32(kHeaderColor); + // Subtle gradient matching theme + ImU32 color_top = ImGui::GetColorU32(ImGui::GetStyleColorVec4(ImGuiCol_WindowBg)); + ImU32 color_bottom = ImGui::GetColorU32(ImGui::GetStyleColorVec4(ImGuiCol_ChildBg)); draw_list->AddRectFilledMultiColor( header_start, ImVec2(header_start.x + header_size.x, header_start.y + header_size.y), color_top, color_top, color_bottom, color_bottom); - // Accent line with pulse effect - float pulse = 0.7f + 0.3f * sinf(header_pulse_); - ImVec4 accent_pulse = ImVec4(kAccentColor.x, kAccentColor.y, kAccentColor.z, pulse); - ImU32 accent_color = ImGui::GetColorU32(accent_pulse); + // Thin accent line (no pulse - matches theme better) + ImU32 accent_color = ImGui::GetColorU32(ImGui::GetStyleColorVec4(ImGuiCol_Separator)); draw_list->AddLine( ImVec2(header_start.x, header_start.y + header_size.y), ImVec2(header_start.x + header_size.x, header_start.y + header_size.y), - accent_color, 3.0f); + accent_color, 1.5f); - ImGui::Dummy(ImVec2(0, 10)); + ImGui::Dummy(ImVec2(0, 8)); - // Title with icon - ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[0]); // Default font (bold if available) - ImGui::TextColored(kAccentColor, "%s AI Chat", ICON_MD_CHAT); - ImGui::PopFont(); + // Title with theme colors + ImGui::TextColored(ImGui::GetStyleColorVec4(ImGuiCol_Text), "%s AI Chat", ICON_MD_CHAT); ImGui::SameLine(ImGui::GetContentRegionAvail().x - 130); diff --git a/src/app/gui/style.cc b/src/app/gui/style.cc index 22f224ef..6b5dc09e 100644 --- a/src/app/gui/style.cc +++ b/src/app/gui/style.cc @@ -95,7 +95,7 @@ void ColorsYaze() { colors[ImGuiCol_FrameBgHovered] = ImVec4(0.28f, 0.36f, 0.28f, 0.40f); colors[ImGuiCol_FrameBgActive] = ImVec4(0.28f, 0.36f, 0.28f, 0.69f); - colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); + colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); // Solid blue checkmark colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); colors[ImGuiCol_SliderGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f); diff --git a/src/app/gui/theme_manager.cc b/src/app/gui/theme_manager.cc index 77960a40..ea275bc7 100644 --- a/src/app/gui/theme_manager.cc +++ b/src/app/gui/theme_manager.cc @@ -203,9 +203,9 @@ void ThemeManager::CreateFallbackYazeClassic() { theme.resize_grip_active = RGBA(199, 209, 255, 230); // 0.78f, 0.82f, 1.00f, 0.90f // Complete ImGui colors with smart defaults using accent colors - theme.check_mark = RGBA(230, 230, 230, 128); // 0.90f, 0.90f, 0.90f, 0.50f - theme.slider_grab = RGBA(255, 255, 255, 77); // 1.00f, 1.00f, 1.00f, 0.30f - theme.slider_grab_active = RGBA(92, 115, 92, 153); // Same as scrollbar for consistency + theme.check_mark = RGBA(66, 150, 250, 255); // Solid blue checkmark (visible!) + theme.slider_grab = RGBA(66, 150, 250, 200); // Blue slider grab + theme.slider_grab_active = RGBA(92, 115, 92, 255); // Solid green when active theme.input_text_cursor = theme.text_primary; // Use primary text color theme.nav_cursor = theme.accent; // Use accent color for navigation theme.nav_windowing_highlight = theme.accent; // Accent for window switching