Skip to content

AI Gate v4.7.0

Choose a tag to compare

@inulute inulute released this 03 Jul 16:05
609b0da

Release: v4.7.0 • Date: 2026-07-03 (UTC)



What's new in v4.7.0


🔒 Security Hardening

Replaced shell.openExternal blocklist with an allowlist — the previous approach blocked a fixed set of dangerous schemes (file:, javascript:, data:, about:). The new allowlist only permits https: and http:, which means any URL scheme not explicitly allowed is rejected by default. This is a fundamentally more secure model.

Tightened Content-Security-Policy to per-directive rules — replaced the broad default-src 'self' 'unsafe-inline' 'unsafe-eval' * fallback with explicit per-directive rules (script-src, style-src, font-src, img-src *, connect-src *). Wildcard is now restricted to img-src and connect-src only, where user-configured tools genuinely require access to arbitrary domains.


🖱️ Drag-to-Reorder Tools in the Sidebar

Tools in the left-hand panel can now be dragged to any position. Built on @dnd-kit/sortable with a PointerSensor (6 px activation threshold), restrictToVerticalAxis, and restrictToParentElement. The expanded sidebar shows a grip handle on hover; the collapsed sidebar uses a full-item drag overlay to keep the hit area accessible. Order is persisted across restarts.


🔍 Ctrl+Scroll Zoom in Webviews

Holding Ctrl and scrolling over a webview now steps through the same zoom levels as Ctrl++ / Ctrl+-. Implemented via a zoom-changed handler on web-contents-created in the main process — no new IPC surface, routes through the existing webviewZoom system.


🐛 Bug Fixes

Fixed tab drag causing a black window — two separate root causes were resolved:

  1. CSS.Transform.toString() in Tab.tsx emits translate3d(), which promotes elements to a GPU compositing layer. On Windows this conflicted with Electron's webview GPU rendering and could crash the GPU process. Switched to a 2D translate().

  2. reorderTabInPanel() received numeric indices computed against the full global toolInstances list, but resolved them against a smaller panel-local list internally. In synced-tabs mode this produced out-of-bounds indices, causing splice to return undefined and throwing a TypeError that crashed the renderer. Fixed by switching the signature to instance IDs and resolving indices safely inside the updater.

Fixed tab reorder having no effect in synced-tabs mode — when Sync tab bar across all panels is enabled, instances is ordered by array position, not positionInPanel. TabBar.handleDragEnd now calls reorderInstances() in synced mode (reorders the global array and updates position) and reorderTabInPanel() in per-panel mode.

Fixed sidebar drag, tab overflow, and auto-collapse layout issues — various layout edge cases in the sidebar collapse behaviour and tab bar overflow handling were resolved.

Removed redundant UpdateService polling intervalUpdateService had its own setInterval in the constructor that fired network requests every 12 h and discarded results. UpdateContext already owns the polling lifecycle with proper useEffect cleanup. Removed the internal timer, startPeriodicCheck(), and CHECK_INTERVAL.

Removed dead window.openExternal assignment in preload — under contextIsolation: true the preload script's window is isolated from the renderer's window, so this assignment was unreachable dead code.


👏 Contributors

Huge thanks to @n3yne for this release — every feature, fix, and security improvement in v4.7.0 came from their work.


New Contributors

@n3yne made their first contribution in #23


📦 Downloads

  • Linux AppImageAI.Gate-4.7.0.AppImage
  • Linux debAI.Gate-4.7.0.deb
  • macOS (Universal)AI.Gate-4.7.0-universal-mac.dmg
  • WindowsAI.Gate-Setup-4.7.0.exe
  • Flatpak (Flathub) — submission in progress, coming soon

❤️ Support

If AI Gate makes your workflow better, consider supporting its development:

Your support helps maintain and improve AI Gate, add new features, keep the app free and open source, and ship timely updates.


Made with ❤️ by inulute