diff --git a/Taskfile.yml b/Taskfile.yml
index c3aaf0957..9cf194e5c 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -71,10 +71,74 @@ tasks:
- echo "MSIX packaging not yet implemented for CEF host. Old Tauri script was removed."
package:macos:
- desc: "[TODO] Package the application for macOS (CEF). Not yet implemented."
+ desc: Package the application for macOS (.app + DMG). Outputs to ~/Desktop.
platforms: [darwin]
+ deps: [build:frontend, build:backend, cef:build]
cmds:
- - echo "macOS CEF packaging not yet implemented. Use cef:package:portable on Windows."
+ - task: cef:bundle
+ - |
+ VERSION=$(node -p "require('./package.json').version")
+ ARCH="arm64"
+ APP="dist/AgentMux.app"
+ MACOS="$APP/Contents/MacOS"
+ FRAMEWORKS="$APP/Contents/Frameworks"
+
+ # Scaffold .app structure
+ rm -rf "$APP"
+ mkdir -p "$MACOS" "$FRAMEWORKS" "$APP/Contents/Resources"
+
+ # CEF host binary (CFBundleExecutable)
+ cp dist/cef/agentmux-cef "$MACOS/agentmux-cef"
+ chmod +x "$MACOS/agentmux-cef"
+
+ # CEF framework — library_loader resolves {exe_dir}/../Frameworks/
+ # which maps to Contents/MacOS/../Frameworks = Contents/Frameworks/ ✓
+ rsync -a "dist/Frameworks/Chromium Embedded Framework.framework" "$FRAMEWORKS/"
+
+ # Backend sidecar — versioned name in exe_dir (sidecar.rs lookup order 1)
+ cp "dist/bin/agentmux-srv-${VERSION}-darwin.${ARCH}" \
+ "$MACOS/agentmux-srv-${VERSION}-darwin.${ARCH}"
+ chmod +x "$MACOS/agentmux-srv-${VERSION}-darwin.${ARCH}"
+
+ # Built frontend — IPC server serves from {exe_dir}/frontend/
+ cp -r dist/frontend "$MACOS/frontend"
+
+ # App icon
+ [ -f build/icon.icns ] && \
+ cp build/icon.icns "$APP/Contents/Resources/AgentMux.icns"
+
+ # Info.plist
+ BUNDLE_ID="ai.agentmux.app.v$(echo $VERSION | tr '.' '-')"
+ printf '%s\n' \
+ '' \
+ '' \
+ '' \
+ " CFBundleIdentifier ${BUNDLE_ID}" \
+ ' CFBundleName AgentMux' \
+ ' CFBundleDisplayName AgentMux' \
+ ' CFBundleExecutable agentmux-cef' \
+ " CFBundleVersion ${VERSION}" \
+ " CFBundleShortVersionString ${VERSION}" \
+ ' CFBundleIconFile AgentMux' \
+ ' LSMinimumSystemVersion 12.0' \
+ ' NSHighResolutionCapable ' \
+ ' NSRequiresAquaSystemAppearance ' \
+ ' com.apple.security.cs.allow-jit ' \
+ ' com.apple.security.cs.allow-unsigned-executable-memory ' \
+ ' com.apple.security.cs.disable-library-validation ' \
+ '' \
+ > "$APP/Contents/Info.plist"
+ echo "✓ Built AgentMux.app (v${VERSION})"
+
+ - |
+ VERSION=$(node -p "require('./package.json').version")
+ xattr -cr dist/AgentMux.app 2>/dev/null || true
+ DMG="dist/AgentMux_${VERSION}_aarch64.dmg"
+ hdiutil create -volname "AgentMux ${VERSION}" \
+ -srcfolder dist/AgentMux.app -ov -format UDZO "$DMG"
+ xattr -d com.apple.quarantine "$DMG" 2>/dev/null || true
+ cp "$DMG" ~/Desktop/
+ echo "✓ DMG → ~/Desktop/AgentMux_${VERSION}_aarch64.dmg"
package:portable:linux:
@@ -431,7 +495,44 @@ tasks:
internal: true
platforms: [darwin]
cmds:
- - echo "macOS CEF bundling not yet implemented"
+ - |
+ VERSION=$(node -p "require('./package.json').version")
+ ARCH="arm64"
+
+ # 1. Locate CEF framework in build output
+ CEF_FW=$(find target -type d -name "Chromium Embedded Framework.framework" \
+ -path "*/cef-dll-sys*/out/*" 2>/dev/null | head -1)
+ if [ -z "$CEF_FW" ]; then
+ echo "❌ Chromium Embedded Framework.framework not found — run cef:build first"
+ exit 1
+ fi
+ echo "Found CEF framework: $CEF_FW"
+
+ # 2. Copy framework to dist/Frameworks/
+ # library_loader resolves {exe_dir}/../Frameworks/ so it must be one level
+ # above dist/cef/ — i.e. dist/Frameworks/
+ mkdir -p dist/Frameworks
+ rsync -a --delete "$CEF_FW" dist/Frameworks/
+
+ # 3. Strip all non-English lproj dirs from framework (~50 MB saved)
+ find "dist/Frameworks/Chromium Embedded Framework.framework/Resources" \
+ -maxdepth 1 -name "*.lproj" ! -name "en.lproj" -exec rm -rf {} + 2>/dev/null || true
+
+ echo "✓ CEF framework → dist/Frameworks/"
+
+ - |
+ VERSION=$(node -p "require('./package.json').version")
+ ARCH="arm64"
+
+ # 4. Versioned sidecar (sidecar.rs looks for {exe_dir}/agentmux-srv-{VERSION}-darwin.arm64)
+ cp "dist/bin/agentmux-srv-${VERSION}-darwin.${ARCH}" \
+ "dist/cef/agentmux-srv-${VERSION}-darwin.${ARCH}"
+
+ # 5. Built frontend (IPC server serves from {exe_dir}/frontend/)
+ rm -rf dist/cef/frontend
+ cp -r dist/frontend dist/cef/frontend
+
+ echo "✓ Bundled macOS runtime to dist/cef/"
cef:bundle:linux:
internal: true
diff --git a/agentmux-cef/src/app.rs b/agentmux-cef/src/app.rs
index e4029bd63..7af77f21a 100644
--- a/agentmux-cef/src/app.rs
+++ b/agentmux-cef/src/app.rs
@@ -262,6 +262,17 @@ wrap_app! {
let rpl_key = CefString::from("renderer-process-limit");
let rpl_val = CefString::from("1");
cmd.append_switch_with_value(Some(&rpl_key), Some(&rpl_val));
+
+ // Bypass macOS Keychain for Chromium's OSCrypt/SafeStorage.
+ // Without this, Chromium prompts the user to allow keychain
+ // access on every launch to store a cookie-encryption key.
+ // AgentMux doesn't store browser passwords so mock keychain
+ // is safe and eliminates the OS security dialog entirely.
+ #[cfg(target_os = "macos")]
+ {
+ let mk_key = CefString::from("use-mock-keychain");
+ cmd.append_switch(Some(&mk_key));
+ }
}
}
diff --git a/agentmux-cef/src/client.rs b/agentmux-cef/src/client.rs
index e40f7f7d8..95a01c19b 100644
--- a/agentmux-cef/src/client.rs
+++ b/agentmux-cef/src/client.rs
@@ -10,6 +10,13 @@ use cef::*;
use std::sync::Arc;
use parking_lot::Mutex;
+// The native OS key event type differs per platform. On macOS/Linux it is an
+// opaque `*mut u8` (NSEvent* / XEvent*); on Windows it is `cef::sys::MSG`.
+#[cfg(windows)]
+type NativeKeyEvent = cef::sys::MSG;
+#[cfg(not(windows))]
+type NativeKeyEvent = u8;
+
use crate::state::AppState;
/// Write a debug line to `%TEMP%\agentmux-close-debug.txt`.
@@ -673,7 +680,7 @@ wrap_keyboard_handler! {
&self,
_browser: Option<&mut Browser>,
event: Option<&KeyEvent>,
- _os_event: Option<&mut cef::sys::MSG>,
+ _os_event: *mut NativeKeyEvent,
is_keyboard_shortcut: Option<&mut ::std::os::raw::c_int>,
) -> ::std::os::raw::c_int {
if let Some(ev) = event {
diff --git a/agentmux-cef/src/main.rs b/agentmux-cef/src/main.rs
index c0f67dcea..81e880873 100644
--- a/agentmux-cef/src/main.rs
+++ b/agentmux-cef/src/main.rs
@@ -109,6 +109,14 @@ fn main() {
tracing::info!("Initializing CEF browser process");
+ // macOS 26 Tahoe compat: CEF 146 calls a private NSApplication selector during
+ // NSDraggingSession setup that was removed in macOS 26. Swizzle
+ // doesNotRecognizeSelector: on NSApplication to log the selector name and
+ // return without throwing NSInvalidArgumentException, allowing drag to proceed.
+ // See: docs/investigations/tab-drag-tearoff-crash-macos.md
+ #[cfg(target_os = "macos")]
+ unsafe { patch_nsapp_unrecognized_selector() };
+
// Single-instance check: if another instance of the same version is
// running, send it a "new window" request via its IPC server and exit.
// Uses a named mutex for detection and a port file for communication.
@@ -207,14 +215,31 @@ fn main() {
.and_then(|p| p.parent().map(|d| d.to_path_buf()))
.unwrap_or_default();
let runtime_dir = exe_dir.join("runtime");
- let base_dir = if runtime_dir.exists() {
+ let _base_dir = if runtime_dir.exists() {
runtime_dir
} else {
// Dev mode: resources are flat alongside the exe in dist/cef/
exe_dir.clone()
};
- let resources_dir = CefString::from(base_dir.to_str().unwrap_or(""));
- let locales_dir = CefString::from(base_dir.join("locales").to_str().unwrap_or(""));
+ // On macOS, pak files and locale paks live inside the CEF framework's
+ // Resources/ directory — not alongside the executable. The framework is
+ // at {exe_dir}/../Frameworks/ (resolved by library_loader above).
+ // Pass that path for both resources_dir and locales_dir so CEF finds
+ // chrome_*.pak, resources.pak, icudtl.dat, and the *.lproj/locale.pak files.
+ #[cfg(target_os = "macos")]
+ let (resources_dir, locales_dir) = {
+ let fw_resources = exe_dir
+ .join("../Frameworks/Chromium Embedded Framework.framework/Resources");
+ // canonicalize() resolves ".." so CEF receives a clean absolute path.
+ let fw_resources = fw_resources.canonicalize().unwrap_or(fw_resources);
+ let s = fw_resources.to_str().unwrap_or("").to_owned();
+ (CefString::from(s.as_str()), CefString::from(s.as_str()))
+ };
+ #[cfg(not(target_os = "macos"))]
+ let (resources_dir, locales_dir) = (
+ CefString::from(_base_dir.to_str().unwrap_or("")),
+ CefString::from(_base_dir.join("locales").to_str().unwrap_or("")),
+ );
// Reuse data_dir from single-instance check as CEF cache path.
// Remove stale lockfile from a previous killed run.
@@ -227,6 +252,14 @@ fn main() {
let cache_dir = CefString::from(data_dir.to_str().unwrap_or(""));
// Configure CEF settings.
+ // On macOS, tell CEF exactly where the framework lives so it can load ICU
+ // and register the bundle correctly — required when running outside a .app.
+ #[cfg(target_os = "macos")]
+ let framework_dir = {
+ let p = exe_dir.join("../Frameworks/Chromium Embedded Framework.framework");
+ p.canonicalize().unwrap_or(p)
+ };
+
let settings = Settings {
no_sandbox: 1,
background_color: 0xFF000000,
@@ -238,6 +271,8 @@ fn main() {
browser_subprocess_path: CefString::from(
std::env::current_exe().unwrap().to_str().unwrap_or("")
),
+ #[cfg(target_os = "macos")]
+ framework_dir_path: CefString::from(framework_dir.to_str().unwrap_or("")),
..Default::default()
};
@@ -290,6 +325,114 @@ fn main() {
tracing::info!("AgentMux CEF host shutdown complete");
}
+/// macOS 26 Tahoe compat: CEF 146 calls private NSApplication selectors (e.g.
+/// `isHandlingSendEvent`) during NSDraggingSession setup that were removed in macOS 26.
+///
+/// The correct fix is to hook `+[NSApplication resolveInstanceMethod:]` — the earliest
+/// point in the ObjC dispatch chain — so missing selectors get a void stub before the
+/// forwarding machinery (`___forwarding___`) is invoked. Swizzling `doesNotRecognizeSelector:`
+/// is wrong here: that method is called FROM inside `___forwarding___`, and returning
+/// normally from it (without throwing) corrupts the forwarding state and causes a second
+/// crash inside `___forwarding___` itself.
+///
+/// Return-type-aware stubs: `isHandlingSendEvent` and similar BOOL guard getters must
+/// return 0 (NO). A void stub leaves x0 = self (truthy), causing CEF to think the app
+/// is already handling a send event and skip normal event routing — breaking window drag.
+/// All other unknown selectors get a void stub, which is safe.
+///
+/// Safety: Called once before CEF initializes. NSApplication is a singleton; adding a
+/// `resolveInstanceMethod:` implementation on its metaclass is safe at startup.
+#[cfg(target_os = "macos")]
+unsafe fn patch_nsapp_unrecognized_selector() {
+ use std::ffi::{c_char, c_void};
+
+ type Id = *mut c_void;
+ type Sel = *const c_void;
+ type Class = *mut c_void;
+
+ extern "C" {
+ fn objc_getClass(name: *const c_char) -> Class;
+ fn object_getClass(obj: Id) -> Class; // on a Class obj → returns metaclass
+ fn sel_registerName(name: *const c_char) -> Sel;
+ fn sel_getName(sel: Sel) -> *const c_char;
+ fn class_addMethod(
+ cls: Class,
+ sel: Sel,
+ imp: usize,
+ types: *const c_char,
+ ) -> u8; // BOOL
+ }
+
+ // Generic void stub for unknown selectors that return nothing (or whose
+ // return value is not used by callers).
+ unsafe extern "C" fn void_stub(_self: Id, _cmd: Sel) {}
+
+ // BOOL stub returning 0 (NO) for guard-style getters. On ARM64, a void stub
+ // leaves x0 = self (non-nil = truthy), which breaks callers like CEF's
+ // sendEvent: guard that skips event routing when isHandlingSendEvent returns YES.
+ unsafe extern "C" fn bool_no_stub(_self: Id, _cmd: Sel) -> u8 { 0 }
+
+ // +resolveInstanceMethod: injected into NSApplication metaclass.
+ // Called by the ObjC runtime the first time an unknown selector is sent to
+ // an NSApplication instance — before ___forwarding___ is ever entered.
+ // We add a typed stub and return YES so the runtime retries the send.
+ unsafe extern "C" fn resolve_instance_method_impl(
+ cls: Class,
+ _cmd: Sel,
+ sel: Sel,
+ ) -> u8 {
+ let name = {
+ let ptr = sel_getName(sel);
+ if ptr.is_null() { "".to_owned() }
+ else { std::ffi::CStr::from_ptr(ptr).to_string_lossy().into_owned() }
+ };
+
+ // These selectors return BOOL and callers act on the value.
+ // Returning truthy (garbage from a void stub) breaks event routing and
+ // prevents window drag from receiving mouse events.
+ const BOOL_NO_SELECTORS: &[&str] = &[
+ "isHandlingSendEvent",
+ "isSendingEvent",
+ ];
+
+ if BOOL_NO_SELECTORS.contains(&name.as_str()) {
+ tracing::warn!(selector = %name, "macOS 26 compat: adding BOOL(NO) stub");
+ class_addMethod(cls, sel, bool_no_stub as usize, b"c@:\0".as_ptr() as _);
+ } else {
+ tracing::warn!(selector = %name, "macOS 26 compat: adding void stub");
+ class_addMethod(cls, sel, void_stub as usize, b"v@:\0".as_ptr() as _);
+ }
+ 1 // YES — resolved; runtime retries the original send
+ }
+
+ let cls = objc_getClass(b"NSApplication\0".as_ptr() as _);
+ if cls.is_null() {
+ tracing::warn!("macOS 26 compat: NSApplication class not found");
+ return;
+ }
+
+ // The metaclass is the "class object" of a class; class methods live there.
+ let metacls = object_getClass(cls as Id);
+ if metacls.is_null() {
+ tracing::warn!("macOS 26 compat: NSApplication metaclass not found");
+ return;
+ }
+
+ let sel = sel_registerName(b"resolveInstanceMethod:\0".as_ptr() as _);
+ // "c@::" = BOOL return, id (Class), SEL (cmd), SEL (queried selector)
+ let added = class_addMethod(
+ metacls,
+ sel,
+ resolve_instance_method_impl as usize,
+ b"c@::\0".as_ptr() as _,
+ );
+ if added != 0 {
+ tracing::info!("macOS 26 compat: injected resolveInstanceMethod: into NSApplication metaclass");
+ } else {
+ tracing::warn!("macOS 26 compat: class_addMethod failed (method already exists?)");
+ }
+}
+
/// Initialize tracing with dual output: rolling daily log file + human-readable stderr.
/// Returns a guard that must be held for the lifetime of the process to ensure log flushing.
fn init_logging() -> tracing_appender::non_blocking::WorkerGuard {
diff --git a/package-lock.json b/package-lock.json
index 7356474a5..0d00da79b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -847,7 +847,6 @@
"cpu": [
"ppc64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -864,7 +863,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -881,7 +879,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -898,7 +895,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -915,7 +911,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -932,7 +927,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -949,7 +943,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -966,7 +959,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -983,7 +975,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1000,7 +991,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1017,7 +1007,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1034,7 +1023,6 @@
"cpu": [
"loong64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1051,7 +1039,6 @@
"cpu": [
"mips64el"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1068,7 +1055,6 @@
"cpu": [
"ppc64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1085,7 +1071,6 @@
"cpu": [
"riscv64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1102,7 +1087,6 @@
"cpu": [
"s390x"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1119,7 +1103,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1136,7 +1119,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1153,7 +1135,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1170,7 +1151,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1187,7 +1167,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1204,7 +1183,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1221,7 +1199,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1238,7 +1215,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1255,7 +1231,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1272,7 +1247,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1649,7 +1623,6 @@
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
"integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
- "dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@@ -1689,7 +1662,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1710,7 +1682,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1731,7 +1702,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1752,7 +1722,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1773,7 +1742,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1794,7 +1762,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1815,7 +1782,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1836,7 +1802,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1857,7 +1822,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1878,7 +1842,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1899,7 +1862,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1920,7 +1882,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1941,7 +1902,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2156,7 +2116,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2170,7 +2129,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2184,7 +2142,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2198,7 +2155,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2212,7 +2168,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2226,7 +2181,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2240,7 +2194,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2254,7 +2207,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2268,7 +2220,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2282,7 +2233,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2296,7 +2246,6 @@
"cpu": [
"loong64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2310,7 +2259,6 @@
"cpu": [
"loong64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2324,7 +2272,6 @@
"cpu": [
"ppc64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2338,7 +2285,6 @@
"cpu": [
"ppc64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2352,7 +2298,6 @@
"cpu": [
"riscv64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2366,7 +2311,6 @@
"cpu": [
"riscv64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2380,7 +2324,6 @@
"cpu": [
"s390x"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2394,7 +2337,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2408,7 +2350,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2422,7 +2363,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2436,7 +2376,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2450,7 +2389,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2464,7 +2402,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2478,7 +2415,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2492,7 +2428,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -4139,7 +4074,7 @@
"version": "22.19.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.13.tgz",
"integrity": "sha512-akNQMv0wW5uyRpD2v2IEyRSZiR+BeGuoB6L310EgGObO44HSMNT8z1xzio28V8qOrgYaopIDNA18YgdXd+qTiw==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
@@ -4166,7 +4101,6 @@
"version": "19.2.14",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
- "dev": true,
"license": "MIT",
"dependencies": {
"csstype": "^3.2.2"
@@ -4176,7 +4110,7 @@
"version": "19.2.3",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"peerDependencies": {
"@types/react": "^19.2.0"
@@ -5199,7 +5133,7 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"readdirp": "^4.0.1"
@@ -6052,7 +5986,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
- "dev": true,
+ "devOptional": true,
"license": "Apache-2.0",
"engines": {
"node": ">=8"
@@ -6194,7 +6128,7 @@
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
"integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
- "dev": true,
+ "devOptional": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
@@ -6552,7 +6486,6 @@
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=12.0.0"
@@ -6646,7 +6579,6 @@
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@@ -6692,7 +6624,7 @@
"version": "4.13.6",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz",
"integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
@@ -7275,7 +7207,7 @@
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz",
"integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT"
},
"node_modules/import-fresh": {
@@ -7409,7 +7341,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -7429,7 +7361,7 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
@@ -7600,7 +7532,7 @@
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
"integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"bin": {
"jiti": "lib/jiti-cli.mjs"
@@ -7857,7 +7789,7 @@
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz",
"integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==",
- "dev": true,
+ "devOptional": true,
"license": "MPL-2.0",
"dependencies": {
"detect-libc": "^2.0.3"
@@ -7890,7 +7822,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -7911,7 +7842,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -7932,7 +7862,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -7953,7 +7882,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -7974,7 +7902,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -7995,7 +7922,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -8016,7 +7942,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -8037,7 +7962,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -8058,7 +7982,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -8079,7 +8002,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -8100,7 +8022,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -9349,7 +9270,6 @@
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -9399,7 +9319,6 @@
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
- "dev": true,
"license": "MIT",
"optional": true
},
@@ -9678,7 +9597,6 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -9733,7 +9651,6 @@
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -10011,7 +9928,7 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">= 14.18.0"
@@ -10350,7 +10267,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"funding": {
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
@@ -10416,7 +10333,6 @@
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz",
"integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.8"
@@ -10518,7 +10434,7 @@
"version": "1.97.2",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.97.2.tgz",
"integrity": "sha512-y5LWb0IlbO4e97Zr7c3mlpabcbBtS+ieiZ9iwDooShpFKWXf62zz5pEPdwrLYm+Bxn1fnbwFGzHuCLSA9tBmrw==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"chokidar": "^4.0.0",
@@ -11158,7 +11074,6 @@
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.5.0",
@@ -11374,7 +11289,7 @@
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz",
"integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"esbuild": "~0.27.0",
@@ -11394,7 +11309,6 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@@ -11466,7 +11380,7 @@
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT"
},
"node_modules/unified": {
@@ -11695,7 +11609,6 @@
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.25.0",
@@ -11862,7 +11775,6 @@
"cpu": [
"ppc64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -11879,7 +11791,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -11896,7 +11807,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -11913,7 +11823,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -11930,7 +11839,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -11947,7 +11855,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -11964,7 +11871,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -11981,7 +11887,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -11998,7 +11903,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12015,7 +11919,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12032,7 +11935,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12049,7 +11951,6 @@
"cpu": [
"loong64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12066,7 +11967,6 @@
"cpu": [
"mips64el"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12083,7 +11983,6 @@
"cpu": [
"ppc64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12100,7 +11999,6 @@
"cpu": [
"riscv64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12117,7 +12015,6 @@
"cpu": [
"s390x"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12134,7 +12031,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12151,7 +12047,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12168,7 +12063,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12185,7 +12079,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12202,7 +12095,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12219,7 +12111,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12236,7 +12127,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12253,7 +12143,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12270,7 +12159,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12287,7 +12175,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -12301,7 +12188,6 @@
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
"integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
- "dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
@@ -12343,7 +12229,6 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,