Conversation
…e forks - Added branch filter to only trigger on main, dev, and release/* branches - Added repository check to skip workflow execution for PRs from forks
…ing (#382) # fix(core): add macOS compatibility for provider loading and URL handling ## Description SmartHopper currently does not work on macOS due to three platform-specific issues that cause crashes or incorrect behavior. This PR addresses all three issues to enable cross-platform compatibility. ### Issue 1: `VerifySignature` crashes on macOS `ProviderManager.VerifySignature()` calls `X509Certificate.CreateFromSignedFile()`, which is a Windows-only API. On macOS, this throws `PlatformNotSupportedException`, preventing any AI provider from loading. **Fix:** Wrap the Authenticode verification block in a `RuntimeInformation.IsOSPlatform(OSPlatform.Windows)` guard. Strong-name verification (which is cross-platform) remains active on all platforms. ### Issue 2: `BuildFullUrl` produces `file://` URLs on macOS `AIProvider<T>.BuildFullUrl()` uses `Uri.TryCreate(endpoint, UriKind.Absolute, out var abs)` to detect whether `endpoint` is already an absolute URL. On Windows, relative paths like `/chat/completions` return `false` from `TryCreate` with `UriKind.Absolute`. However, on macOS, the same call returns `true` and produces a `file:///chat/completions` URI, causing the base URL concatenation logic to be skipped entirely. This results in HTTP requests being sent to `file://` URLs, which fail silently. **Fix:** Add an additional scheme check: `abs.Scheme == Uri.UriSchemeHttp || abs.Scheme == Uri.UriSchemeHttps`. This ensures only actual HTTP/HTTPS URLs are treated as absolute, and relative paths like `/chat/completions` are correctly appended to the provider's base URL. ### Issue 3: `ComponentStateManager` deadlock on macOS `ProcessTransitionQueue()` fires state transition events (`StateExited`, `StateEntered`, `TransitionCompleted`) while holding `stateLock`. On macOS, Grasshopper's threading model can cause event handlers to re-enter methods that also acquire `stateLock`, leading to a deadlock. This manifests as the UI freezing when components attempt state transitions. **Fix:** Refactor the transition logic to collect events inside the lock but fire them outside: - Extract event-firing logic from `ExecuteTransition` into a new `ExecuteTransitionCore` that returns transition info without firing events. - Collect all transition results in a list while holding the lock. - Release the lock via `Monitor.Exit`, fire all collected events, then re-acquire via `Monitor.Enter`. - Add a new `FireTransitionEvents` helper method for clarity. ### Issue 4 (NOT FIXED): `WebChatDialog` crashes when opening Chat UI on macOS `WebChatDialog.LoadInitialHtmlIntoWebView()` calls `this._webView.LoadHtml(html, new Uri("https://smarthopper.local/"))`. On macOS, the Eto.Forms `WKWebViewHandler.LoadHtml()` implementation calls `WKWebView.LoadFileUrl(baseNSUrl, baseNSUrl)` for any non-null `baseUri`, but `WKWebView.LoadFileUrl()` only accepts `file://` URLs. Passing `https://smarthopper.local/` triggers an `NSInvalidArgumentException: https://smarthopper.local/ is not a file URL`, crashing Rhino. This affects the CanvasButton chat window (the icon in the top-right corner of the Grasshopper canvas). The crash occurs when the WebView is first initialized. **Root cause:** Eto.Forms macOS `WKWebViewHandler.LoadHtml()` (line 323-330 in the Eto source): ```csharp public void LoadHtml(string html, Uri baseUri) { var baseNSUrl = baseUri.ToNS(); if (baseNSUrl != null) Control.LoadFileUrl(baseNSUrl, baseNSUrl); // BUG: only works with file:// URLs Control.LoadHtmlString(html, baseNSUrl); } ``` **Possible fix:** In `WebChatDialog.cs` line 970, pass `null` as `baseUri` on non-Windows platforms (or pass a `file://` temp directory URI). This would cause `LoadHtmlString` to use `about:blank` as the origin, which should be sufficient since JS-to-C# communication uses `WKUserContentController.AddScriptMessageHandler()` (not origin-dependent). However, this fix has not been tested yet and is NOT included in this PR. ## Testing Done - Built the entire solution on macOS (Apple Silicon, .NET 9.0.304 SDK, targeting net7.0) with 0 errors. - Deployed all compiled assemblies to Grasshopper Libraries on macOS Rhino 8.27. - Verified AI provider loading succeeds (DeepSeek provider loaded and functional). - Tested AI chat interaction via Grasshopper Button → AiStatefulAsyncComponent pipeline, confirmed successful API responses and GhJSON output. - Verified that the `BuildFullUrl` fix correctly constructs URLs like `https://api.deepseek.com/chat/completions` instead of `file:///chat/completions`. - **Known issue:** The CanvasButton chat UI (WebChatDialog) still crashes on macOS due to an Eto.Forms `WKWebView.LoadFileUrl()` bug when passed an `https://` base URI. This is documented as Issue 4 above but is NOT fixed in this PR. ## Checklist - [x] This PR is focused on a single feature or bug fix - [ ] Version in Solution.props was updated, if necessary, and follows semantic versioning - [x] CHANGELOG.md has been updated - [x] PR title follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format - [x] PR description follows [Pull Request Description Template](https://github.com/architects-toolkit/SmartHopper/blob/main/CONTRIBUTING.md#pull-request-description-template)
…ceholders - Updated SolutionVersion from 1.3.0-alpha to 1.4.0-dev.260215 - Updated bug report template placeholders to reflect current versions (RH8.28, SmartHopper 1.4.0-alpha) - Added explicit import of Solution.props in Directory.Build.props - Added conditional check for SolutionVersion property to prevent empty version values
…eadlocks - Moved all event invocations outside stateLock to prevent re-entrant lock acquisition - Refactored ProcessTransitionQueue to collect transition results inside lock and fire events after release - Updated ExecuteTransitionCore to return rejection info instead of firing TransitionRejected directly - Modified ForceState to fire events outside lock - Updated debounce methods (StartDebounce, CancelDebounce) to fire events outside lock
… and secure key storage - Modified SmartHopperSettings constructor to accept encryptionVersion parameter (defaults to 1 for backward compatibility) - Updated Load() method to detect first-run installations and initialize with encryption version 2 - Added automatic encryption key creation and secure storage for new installations - Enhanced debug logging for settings save operations including TrustedProviders content - Updated CHANGELOG.md to document the fix
- Reduced textWidth from 360 to 100 for testing - Simplified contentHeight calculation to use only messageHeight - Updated MinimumSize height to be dynamic based on contentHeight (clamped to 400px max) - Commented out previous contentHeight formula for reference
…or LoadHtml - Added platform detection using RuntimeInformation.IsOSPlatform(OSPlatform.Windows) - Modified LoadInitialHtmlIntoWebView to pass null baseUri on non-Windows platforms - Added explanatory comment about WKWebView.LoadFileUrl() limitation on macOS - Updated CHANGELOG.md to document URL handling fix for macOS compatibility
…omatic version detection - Added VersionHelper class to Infrastructure.Utils for centralized version management - GetFullVersion() returns complete version with commit hash - GetDisplayVersion() returns user-friendly version without commit hash - IsDevelopment(), IsPrerelease(), IsStable() methods for version type detection - GetPrereleaseTag() extracts prerelease identifier (alpha/beta/rc) - Added comprehensive unit tests for VersionHelper (
…DLLs - Added automated hash generation in release workflow (release-4-build.yml) - Calculate SHA-256 hashes for all provider DLLs across platforms (net7.0-windows, net7.0) - Generate versioned JSON manifest with hash values, metadata, and build info - Upload hash manifest as release asset - Publish hash manifest to main branch under .github/pages/hashes/ - Create index.html for hash repository with version listing
…d GitHub Pages publishing
…o GitHub Actions and hash calculation tool - Added version format validation (semantic versioning regex) across all actions and tools - Added platform name validation to prevent path traversal attacks (no slashes, dots, or invalid characters) - Added artifacts/pages directory sanitization to strip path traversal sequences (..\, ../) - Added repository format validation (owner/repo pattern)
…riptions - Renamed test-build-and-hash.yml to user-build-and-hash.yml - Renamed test-publish-pages.yml to user-publish-pages.yml - Updated workflow names from "🧪 Test" to "👤 User" prefix - Simplified workflow descriptions to remove "test" terminology
…Infrastructure project
… codebase - Fixed inconsistent blank line spacing in multiple files - Standardized whitespace around code blocks and statements - Corrected variable references in PR version validation workflow (prVersion → version, targetVersion → version) - Removed trailing whitespace and normalized line endings - Applied consistent formatting to switch statements, conditional blocks, and method chains
…detect path traversal patterns - Enhanced regex to explicitly check for leading/trailing dots and embedded dot sequences - Changed from '[\\/\.\.:]|^\.|\..' to '[\\/]|^\.\.|^\.|.*\.\..*|.*:$' for more precise validation - Prevents path traversal attacks while maintaining clear pattern matching logic
…t regex pattern - Changed from blocklist approach (checking for invalid characters) to allowlist approach - New regex '^[a-zA-Z0-9\.-]+$' only permits alphanumeric characters, dots, and hyphens - Provides clearer validation logic while maintaining protection against path traversal attacks
…ovider-hashes action to use allowlist regex pattern - Changed from blocklist approach (checking for invalid characters) to allowlist approach - New regex '^[a-zA-Z0-9\.-]+$' only permits alphanumeric characters, dots, and hyphens - Provides clearer validation logic while maintaining protection against path traversal attacks
…-provider-hashes action - Changed output names from kebab-case to SCREAMING_SNAKE_CASE (hash-file → HASH_FILE, hash-count → HASH_COUNT) - Maintains consistency with internal step output variable naming convention
- Removed automatic PR commenting from pr-build-hash-validation.yml workflow - Removed automatic PR commenting from pr-version-validation.yml workflow - Validation results still visible in workflow logs and job summaries
…tion workflow - Added git ls-tree check to verify hashes directory exists on target branch before checkout - Enhanced error handling for git checkout failures with proper exit code management - Added explicit conflict detection flag to track validation state - Improved logging to distinguish between missing directory and actual conflicts - Prevents false positives when hashes directory doesn't exist on target branch
…lity improvements (#383) # Description This PR implements comprehensive security enhancements and macOS compatibility improvements for SmartHopper: **Security Enhancements:** - Added SHA-256 hash verification system for AI provider DLLs to protect against tampered code - New "Verify Providers Hash" menu item for manual provider integrity verification - Comprehensive verification dialog with detailed status and hash comparison - Automatic hash generation during release workflow with public hash repository - Platform-appropriate security: Authenticode + hash verification on Windows, hash-only on macOS **macOS Compatibility:** - Fixed provider loading on non-Windows platforms by skipping unsupported Authenticode verification - Resolved URL handling issues that caused incorrect file:// URI generation - Fixed ComponentStateManager deadlocks by refactoring event firing outside state locks - Enhanced WebChatDialog to prevent crashes on macOS by using null baseUri for LoadHtml **UI Improvements:** - Enhanced About dialog with automatic version detection using new VersionHelper class - Added platform information display for better user support **Infrastructure:** - Added comprehensive input validation and sanitization to GitHub Actions - Created reusable GitHub Actions for build, hash calculation, and publishing - Refactored test workflows to user workflows with updated descriptions ## Breaking Changes No breaking changes. All changes are backward compatible and enhance existing functionality. ## Testing Done - Verified SHA-256 hash verification does not cause issues when hash file cannot be retrieved from the internet on Windows - Tested provider loading functionality on Windows platforms - Confirmed ComponentStateManager works well on Windows - Validated WebChatDialog works on Windows - Tested enhanced About dialog version detection Testing on MacOS is pending because I do not have any to try it on. ## Checklist - [x] This PR is focused on a single feature or bug fix - [x] Version in Solution.props was updated, if necessary, and follows semantic versioning - [x] CHANGELOG.md has been updated - [x] PR title follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.1.0/) format - [x] PR description follows [Pull Request Description Template](https://github.com/architects-toolkit/SmartHopper/blob/main/CONTRIBUTING.md#pull-request-description-template)
… fixes (#384) This PR prepares the release for version 1.4.0-alpha with version update and code style fixes: - Updated version in Solution.props - Updated changelog with closed-solved issues - Updated README badges
marc-romu
approved these changes
Feb 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SmartHopper 1.4.0: Enhanced Security and MacOS Compatibility
This release introduces critical security enhancements with SHA-256 provider hash verification and significantly improves macOS compatibility, making SmartHopper more secure and accessible across platforms.
🔒 Provider Hash Verification
Added comprehensive SHA-256 hash verification system for AI provider DLLs to enhance security across all platforms. The new verification system includes a "Verify Providers Hash" menu item for manual integrity checks, automatic hash generation during release workflows, and multi-tier verification with graceful degradation when hashes are unavailable.
🖥️ Enhanced About Dialog
Improved About dialog now automatically displays current SmartHopper version and platform information using the new VersionHelper class, providing users with clear system information at a glance.
🍎 macOS Compatibility Improvements
Significant enhancements for macOS users including provider loading support on non-Windows platforms with appropriate security warnings, fixed URL handling to prevent incorrect file:// URI generation, and resolved component state management deadlocks by reorganizing event firing patterns.
🔧 Settings and Encryption
Fixed first-time initialization to use EncryptionVersion 2 by default, which stores a local hash for secrets encryption, improving the security of stored API keys and sensitive configuration data.
🛡️ Security Enhancements
Enhanced provider security with SHA-256 hash verification system to protect against tampered provider DLLs, implementing platform-appropriate security measures with Authenticode + hash verification on Windows and hash verification on macOS.
🛠️ Technical Requirements
🤝 We Value Your Feedback!
Help shape SmartHopper's future by:
We hope you enjoy these enhanced security and compatibility improvements!
Happy designing! 🎨