From 285c3bcaaee2a868ec953426fc9a3c9e0c83a323 Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Mon, 20 Apr 2026 15:41:15 +0300 Subject: [PATCH] Migrate desktop shell from Tauri to Electron (#964) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(electron): scaffold Electron desktop package Main + preload + ssh manager, packaging scripts, icons, root build/lint/type-check wiring. * feat(ui): add Electron runtime detection and desktopNative facade isElectronShell via window.__OPENCHAMBER_ELECTRON__, isDesktopShell now covers both. desktopNative wraps window/title/theme calls so UI avoids direct Tauri imports. revealDesktopPath added. * refactor(ui): route window/title/theme/export through desktopNative SessionSidebar, MultiRunLauncher, useWindowTitle, ThemeSystemContext, exportSession drop direct @tauri-apps imports. * refactor(ui): treat all desktop shells uniformly device.ts switches Tauri-only checks to isDesktopShell. Header OpenInApp button uses actionDirectory so it falls back to the active project path. * fix(ui): menu Copy clipboard fallback and softer sidebar tint useMenuActions falls back to Clipboard API for the native Copy action when the page doesn't intercept. cssGenerator lowers sidebar strong/soft alpha so the tinted surface reads gentler. * chore(electron): mirror Tauri build/type-check script shape build script becomes no-op so root 'bun run build' skips packaging. Syntax validation (node --check) moves into type-check. electron:build root script still runs full sidecar+bundle+electron-builder. * fix(electron): sync app identity, preload path, boot outcome, dev entry Read version from packages/electron/package.json so 'electron ./main.mjs' dev entry reports the app version instead of Electron's. Bump electron package to 1.9.6 for workspace parity. Resolve preload via app.getAppPath() in prod (bundle lives in dist-bundle while preload.mjs ships at app root). Compute and inject __OPENCHAMBER_DESKTOP_BOOT_OUTCOME__ in main + preload so the loading gate dismisses (mirrors Tauri Rust injection). Dev entry uses ./main.mjs to bypass the stale dist-bundle so source edits apply. * refactor(open-in-app): split directory and file flows Header button now opens the project/worktree directory only — drop activeFilePath prop and its Header prop passthrough. FilesView editor dropdown opens the active file only via new openDesktopFileInApp. Electron main.mjs mirrors Tauri's open-chain logic: buildOpenProjectSpecs (finder/terminal direct, vscode-like via CLI -n, JetBrains via open -na --args) and buildOpenFileSpecs (finder -R reveal, terminal opens parent dir, editors via CLI or open -a). runSpecChain falls through specs until one exits 0. * fix(files-view): keep floating toolbar mounted while its dropdowns are open Portalled Base UI menu popups render outside floatingToolbarRef. The document mousedown listener and onMouseLeave collapsed the toolbar as soon as the popup appeared, unmounting the DropdownMenu root and swallowing clicks on its items. Track open dropdowns via onOpenChange and skip the collapse while count > 0; also ignore mousedowns that land inside a dropdown-menu-content/item. * feat(electron): add quit confirmation with risk poller Mirrors Tauri's macOS-only behavior: poll /api/openchamber/scheduled-tasks/status and /api/openchamber/tunnel/status every 5s. If active tunnel or running/enabled scheduled tasks are detected, Cmd+Q / dock Quit / menu Quit shows a native warning dialog listing reasons; otherwise quit proceeds silently. performConfirmedQuit persists window state, kills sidecar, shuts down SSH, and fires a 1500ms unref'd safety timeout that calls app.exit(0) if the normal quit sequence stalls. * feat(notifications): fix payload parsing, restore-on-click, session deep-link Normalize input so both sidecar stdout path (flat) and UI IPC path ({ payload: {...} }) work; previous destructuring missed requireHidden (camelCase) and the payload wrapper so notifications showed with empty body. Click handler restores the window if minimized, shows it if hidden, and focuses. When the notification payload carries sessionId, emit openchamber:open-session which the App listener routes to setCurrentSession — matches the PWA service-worker deep-link behavior. macOS notifications now also use sound 'Glass' for parity with Tauri. * chore(electron): bump to Electron 41 + latest updater/context-menu electron ^38.2.0 -> ^41.2.1 electron-updater ^6.6.2 -> ^6.8.3 electron-context-menu ^4.0.4 -> ^4.1.2 Dev boot verified: main process starts, preload exposes globals, API server + quit risk poller + autoUpdater all initialize without errors. * fix: keep todo row alignment stable when expanding text Keep checkbox and action buttons vertically centered in collapsed todo rows Prevent first todo line from shifting when expanding to multiple lines * fix: make commit highlights visible and input behavior reliable Switch commit message field to native textarea for predictable auto-resize Fix AI highlights append flow so inserted text is applied consistently Make chat scroll-to-bottom control fully circular * style: increase chat bubble corner radius consistency Use larger radius for user chat message bubbles Match chat input container radius to user message styling * feat(electron): adopt OpenCode playbook improvements mac: hardenedRuntime + entitlements.mac.plist + notarize + dmg.sign for Apple notarization parity. single-instance lock + openchamber:// protocol with session/project/host routing (host switch done fully in main via activateMainWindow). setAppUserModelId for Win toast identity; proxy-bypass-list switch; chdir(homedir) for Finder-launch cwd safety. shell env probe (\$SHELL -il -> -l) merged into sidecar spawn; PATH deduped. electron-log with 5MB rotation + 7-day cleanup; autoUpdater.logger wired; startup info log. webContents zoom locked to 1 (zoom-changed + did-finish-load). UI: openchamber:open-project -> useDirectoryStore.setDirectory. * fix(electron): make bootOutcome mutable across re-navigation + project deep-link host deep-link used to land on chooser because contextBridge exposed bootOutcome as read-only; initScript re-assignment became a silent no-op. drop preload's contextBridge for bootOutcome, inject it via main-world initScript, and move injection from did-finish-load to dom-ready so it lands before React mounts. project deep-link updated currentDirectory only; activeProjectId stayed stale so the sidebar didn't highlight the new project. switch to projectsStore.setActiveProject (or addProject for new paths) which updates both. add log.info around deep-link dispatch + host switch for diagnostics. * fix(electron): desktop_hosts_set IPC args + persist initialHostChoiceCompleted + re-eval bootOutcome UI calls invoke('desktop_hosts_set', { input: {...} }) but main was reading args.config — every onboarding 'i've completed installation' / host-dialog save wrote nothing, so desktopDefaultHostId stayed null and the chooser screen looped forever. also: - writeDesktopHostsConfig now persists desktopInitialHostChoiceCompleted so the tauri-compat flag survives writes. - readDesktopHostsConfig returns initialHostChoiceCompleted so the UI-side config mirror is complete. - after writing hosts, recompute state.bootOutcome + state.initScript; a subsequent window.location.reload() picks up target=local/status=ok via dom-ready injection without needing a full app restart. - app.setName('OpenChamber') early (pre log.initialize) so electron-log logs land in ~/Library/Logs/OpenChamber/ instead of the package-derived '@openchamber/electron' path. * chore(electron): rename appId to dev.openchamber.desktop ai.opencode.* is the OpenCode team's reverse-DNS namespace; OpenChamber should not squat there. now that we're on Electron, drop the tauri-era inherited identifier and claim our own under openchamber.dev. user-facing productName stays "OpenChamber". tauri identifier left as-is — legacy shell on the way out. * feat(ci): add electron build+notarize+publish jobs to release workflow three new jobs in release.yml, running in parallel with tauri: - build-desktop-electron-macos: matrix(arm64, x86_64) on macos-26; installs Developer ID via keychain, runs build:sidecar + bundle:main + electron-builder --mac --arch <> --publish=never (with APPLE_ID / APPLE_APP_SPECIFIC_PASSWORD / APPLE_TEAM_ID env mapped from existing secrets). verifies hardened runtime, stapled notary ticket, required entitlements. uploads DMG/ZIP/blockmaps to the release and emits per-arch latest-mac.yml as a GH artifact. - combine-electron-manifests: downloads latest-yml-*-apple-darwin artifacts, runs the existing finalize-latest-yml.mjs to merge per-arch files entries into a single latest-mac.yml, uploads combined yml to the release. - finalize-release: now also waits on the two new jobs before flipping the draft release to published. also: explicit artifactName in electron-builder config so arm64 and x64 dmg/zip never collide. electron-updater in main.mjs (setFeedURL btriapitsyn/openchamber) fetches this latest-mac.yml on desktop_check_for_updates; downloadUpdate / quitAndInstall wire through our existing IPC handlers unchanged. * docs: future-agent brief for tauri -> electron auto-update cutover self-contained plan for the one-shot migration release that carries existing tauri installs into the electron shell via tauri's updater. written so a fresh agent with no branch context can execute it. covers: the trick (repackage signed electron .app as a tauri tarball, minisign with existing TAURI_SIGNING_PRIVATE_KEY), workflow surgery on release.yml, rollback plan, validation steps against a real tauri install, and edge cases (CFBundleIdentifier change, notification perms re-prompt, deep-link re-registration). * docs: soften framing of cutover playbook (no user-shaming) * chore: mark electron as primary desktop shell; tune dmg installer window AGENTS.md: explicit note that new desktop work lands in packages/electron/, packages/desktop/ (tauri) is maintenance-only until the cutover described in docs/TAURI_TO_ELECTRON_CUTOVER.md. updated runtime/entry-points/build-commands sections accordingly. electron/package.json build.dmg: cleaner title ("OpenChamber 1.9.6" without -arch suffix), 660x400 window matching the tauri layout users are used to, icon size 128, explicit app/Applications positions. * refactor(web): drop bun-specific runtime deps from server - 11 test files migrated bun:test -> vitest; API (describe/it/expect) is drop-in; all 73 tests pass under vitest run. - bun:sqlite -> better-sqlite3 in git/service.js::syncSandboxesToOpenCodeDb. api shift is db.query().get()/run() -> db.prepare().get()/run(). - add "test": "vitest run" script in packages/web. no production code used Bun.* APIs; server is Express-on-Node already. this commit removes the remaining bun-runtime shape so the server module can be imported and booted inside an electron main process. * feat(electron): boot web server in-process, drop sidecar subprocess the electron main process now imports @openchamber/web/server/index.js as a workspace dependency and calls startWebUiServer({...}) directly. the returned handle exposes getPort() / stop() and the notification emitter takes an onDesktopNotification callback, so we no longer spawn a bun-compiled sidecar binary and no longer parse stdout for the one-line notify protocol. - packages/electron/package.json: +@openchamber/web (workspace:*); extraResources drops 'sidecar'; build:sidecar script renamed to build:web-assets (kept the vite build step, dropped the bun compile step). - packages/electron/main.mjs: remove spawn/kill-stale-sidecar/sidecar path resolver/stdout-prefix parser; rewrite spawnLocalServer to probe a free port (stored | DEFAULT_DESKTOP_PORT | OS-assigned) then import server and await startWebUiServer; killSidecar calls handle.stop({ exitProcess: false }); hoist user shell env (PATH, etc.) onto process.env once so opencode / git / rg children still inherit the expected runtime environment. - packages/web/server/lib/notifications/emitter-runtime.js: accept an onDesktopNotification callback (late-bindable via setOnDesktopNotification). when set, notifications are dispatched through the callback instead of process.stdout; tauri path still uses stdout when no callback is bound. - packages/web/server/index.js: main() wires options.onDesktopNotification to notificationEmitterRuntime.setOnDesktopNotification. - release.yml + AGENTS.md updated for the new script name + runtime shape. payoff: -300ms cold start on mac, single process in activity monitor, no stdio IPC, no bun binary in the packaged app. tauri sidecar path is untouched. * build(electron): rebuild native deps explicitly, bump electron-builder the previous build failed because electron-builder 24.13.3 tried to run \`bun rebuild\` on native deps (better-sqlite3, node-pty) and bun has no rebuild subcommand; it also couldn't find prebuild-install because bun hoists under node_modules/.bun/@/ and never populates node_modules/.bin for transitive deps. fix: - bump electron-builder devDep to ^26, whose packageManager detection understands bun workspace layouts. - add @electron/rebuild devDep + scripts/rebuild-native.mjs. the script rebuilds better-sqlite3 / node-pty / bun-pty against the installed electron version before electron-builder is invoked. - set build.npmRebuild=false so electron-builder no longer attempts its own broken PM-based rebuild. - package script: build:web-assets -> bundle:main -> rebuild:native -> electron-builder. verified: CSC_IDENTITY_AUTO_DISCOVERY=false bun run electron:build produces signed-ad-hoc dmg/zip/blockmap/latest-mac.yml; artifacts land under packages/electron/dist as expected. cold-start from Applications should work (native bindings now match electron 41 node ABI). * fix(electron): externalize web server + native deps from main bundle the ESM bundle was statically inlining @openchamber/web transitively, which pulled in bun-pty/src/terminal.ts with its top-level \`import { dlopen } from "bun:ffi"\`. node's ESM loader parses every static import when the bundle loads, so the bun:ffi scheme crashed the packaged app at startup with ERR_UNSUPPORTED_ESM_URL_SCHEME — the runtime guard (if (globalThis.Bun) { await import('bun-pty') }) never got a chance to skip it. fix: bundle-main.mjs marks @openchamber/web (+ its bun-pty / node-pty / better-sqlite3 transitives) as external. the dynamic \`await import('@openchamber/web/server/index.js')\` in main.mjs stays a runtime resolution; the conditional bun-pty import stays dynamic; native modules load from node_modules via the standard resolver. * perf(web): classify UI-only deps as devDependencies, shrink packaged app packages/web is a hybrid package: server code in server/, react UI source in src/, compiled UI output in dist/. the server serves dist/ as static files — it never imports react/radix/codemirror/etc. at runtime. but electron-builder, npm install, and similar tools treat everything under "dependencies" as shipping surface, so all of react + @radix-ui/* + @codemirror/* + @fontsource/* + @simplewebauthn/browser + cmdk + ghostty-web + ... were landing in app.asar even though the same code is already baked into dist/ chunks. move ~24 UI-only packages to devDependencies. vite + its plugins still install them in dev (bun install fetches devDependencies in workspaces), so \`bun run build\` is unchanged. consumers doing \`npm install @openchamber/web\` no longer pull ~150MB of unused browser-side modules. measured on aarch64 darwin build: - app.asar: 281MB -> 44MB (-237MB, -84%) - .dmg: 320MB -> 132MB (-59%) - .zip: 305MB -> 129MB (-58%) verified type-check, ui build, 73 vitest tests, packaged launch. * chore(electron): center dmg installer icons, use cream brand background dmg-builder 26 ignored our previous dmg.contents positions against its template background (they stayed at template coords, producing misalignment with the drawn arrow). switch to a solid backgroundColor (#FFFCF0, the splash light tone) so the template image is dropped entirely and our coordinates are authoritative. window tuned to 540x340, iconSize 100, iconTextSize 13. dmgbuild treats contents coordinates as icon *centers* (not top-left), so with iconSize=100 in a 540 window, x=180 and x=360 place left and right clusters with equal 130px gaps on both sides of the window. y=140 vertically centres the icon+label pair. * fix(electron): eliminate main-thread freezes in in-process server Three blocking paths were running sync work on the Electron main event loop, causing multi-second UI freezes under the new in-process server: - package-manager.detectPackageManagerDetails fired spawnSync(pnpm/npm/ yarn/bun bin -g) with 10s timeouts. In desktop runtime PM detection is pointless (app is .app bundle, updates via electron-updater) — short- circuit when OPENCHAMBER_RUNTIME=desktop. This was the ~5s freeze. - buildInstalledApps iterated 22 OPEN_IN_APPS × spawnSync(mdfind, sips). Converted to execFile promises so child waits yield to the loop. - orphan-project-file recovery re-scanned disk on every settings read (3+/s from fs/list/etc). Cache the outcome per process lifetime. Also: resolveProjectDirectory prefers settings.lastDirectory over activeProjectId so file-open from sidebar/chat doesn't 400 with "Path is outside of active workspace" after the user navigates. Plus dropdown typeahead fixes in DesktopHostSwitcher/BranchSelector: stopPropagation on input keys so cmdk doesn't swallow typing. * feat(electron): restore desktop LAN access for in-process server spawnLocalServer now reads settings.desktopLanAccessEnabled and binds on 0.0.0.0 when enabled, so phones/tablets on the same Wi-Fi can open the app via http://:. Adds desktop_get_lan_address IPC (UDP-connect route lookup with networkInterfaces fallback) for the settings UI to show the reachable URL. UI and settings plumbing already existed from the sidecar build; only the Electron main-process wiring was missing. * chore: added electron package to version bump script * fix(electron): address PR review — harden IPC surface + polish P1 security: - Gate openchamber:invoke and openchamber:dialog:open by webContents origin. Only local (loopback / dev file://) senders can call desktop_*. Blocks remote hosts loaded via DesktopHostSwitcher from reading local files, opening apps, relaunching, etc. - desktop_read_file now refuses paths outside $HOME / tmpdir and denies .ssh/.aws/.gnupg/.config/gh/credentials + .env/.pem/.key by name (defense-in-depth behind the origin gate). P2: - webPreferences.sandbox:false: add comment explaining preload needs Node (contextBridge+ipcRenderer) and why flipping to true would break IPC. - desktop_set_vibrancy: comment the intentional no-op (no Electron equivalent for the Tauri NSVisualEffectView path), drop requiresRestart. - desktopNative.ts: replace isTauriShell() guards with isDesktopShell() so the semantics match (previous check worked only because Electron preload exposes a __TAURI__ shim). - AGENTS.md: correct entry description — server runs in-process, not as a sidecar subprocess. * fix(electron): stop leaking desktop shell APIs to remote renderer pages Preload was exposing __TAURI__ and __OPENCHAMBER_ELECTRON__ unconditionally, so after DesktopHostSwitcher navigated the window to a remote OpenChamber instance the remote UI saw isDesktopShell() === true and tried to invoke desktop_* IPC. The main-process origin gate then threw "IPC not available for this origin", surfacing as a user-visible error on the onboarding screen of the remote. Preload re-runs on cross-origin navigation; compute current origin up front and only expose the shell globals + the openchamber:emit listener when the document is loopback / state.localOrigin / file://. Remote pages now look like a plain web runtime — no IPC path to reject. * fix(electron): restore remote UI shell integration via per-command gate Previous commit stripped __TAURI__ / __OPENCHAMBER_ELECTRON__ from remote pages wholesale, which broke DesktopHostSwitcher for anyone switched to a remote instance: no hosts list, "Unknown" probe status, open-in-new- window dead. Also lost window chrome affordances that the remote UI needs to render correctly inside the Electron shell. Switch from an origin-level gate to a per-command allowlist: - preload.mjs exposes __TAURI__ and __OPENCHAMBER_ELECTRON__ on every page (shell identity + IPC channel). __OPENCHAMBER_LOCAL_ORIGIN__ and __OPENCHAMBER_MACOS_MAJOR__ also go everywhere since HostSwitcher and window chrome depend on them and neither grants capability. __OPENCHAMBER_HOME__ stays local-only (leaks the OS username and is misleading if consumed as a workspace hint on a remote page). - main.mjs ipcMain.handle accepts a curated COMMANDS_SAFE_FOR_REMOTE set (hosts_get, host_probe, new_window, new_window_at_url, set_window_*, is_window_fullscreen, start_window_drag, get_app_version, get_lan_address). Filesystem, shell.openPath, installed-apps scans, app relaunch, auto-update, hosts_set, dialog:open, read_file stay local-only — remote UI doesn't need them and can't weaponize them. * ci(release): rebuild native modules against Electron ABI before packaging Electron job skipped rebuild:native so bun install's Node-ABI builds of better-sqlite3/node-pty/bun-pty shipped into the asar — packaged app would crash on require. Local bun run package runs the step via scripts/rebuild-native.mjs (npmRebuild is disabled in package.json); mirror it in CI and pass ELECTRON_BUILDER_ARCH so the x64 matrix cross-builds from the arm64 runner. Tauri job untouched — both builds continue to produce side-by-side release artifacts (latest.json for Tauri, latest-mac.yml for Electron) so each shell's updater finds its own manifest. * ci(release): split Electron arm64/x64 onto native macOS runners Both Electron matrix entries were running on macos-26 (arm64) and cross-building x64 from there. Works for Rust/Tauri; brittle for native Node modules — better-sqlite3, node-pty, bun-pty (with its rust-pty crate) each have their own cross-target quirks. Pin arm64 → macos-14 and x64 → macos-13 so node-gyp and @electron/rebuild build against the host arch. ELECTRON_BUILDER_ARCH now just mirrors the runner for clarity. * Revert "ci(release): split Electron arm64/x64 onto native macOS runners" This reverts commit f217880e49609cf1418818af0f837b333dbb6f42. * ci(test-build): add Electron DMG job to arm64 dispatch workflow Parallel job to the existing Tauri DMG builder, same runner + Apple cert path. Mirrors the release workflow steps (build:web-assets, bundle:main, rebuild:native, electron-builder) so maintainers can smoke-test a signed+notarized Electron DMG before merging. * ci: use electron-builder v26 boolean arch flags v26 dropped --arch in favour of per-arch booleans (--arm64, --x64, etc.). Test build was failing at dispatch time; release job had the same bug latent. Switch both to the supported form. * fix(electron): route external links to the system browser clicks and window.open calls with non-local URLs were loading inside the Electron BrowserWindow (or spawning a second Electron window as a makeshift browser). Add an origin-aware navigation guard to each window: loopback / state.localOrigin / configured desktop hosts keep their existing in-window behaviour (HostSwitcher, in-window probes); everything else hands off to shell.openExternal so http/https links open in the user's default browser. --- .github/workflows/build-macos-arm64-dmg.yml | 76 + .github/workflows/release.yml | 164 +- AGENTS.md | 30 +- bun.lock | 777 +++++- docs/TAURI_TO_ELECTRON_CUTOVER.md | 349 +++ package.json | 5 + packages/electron/.gitignore | 13 + packages/electron/main.mjs | 2195 +++++++++++++++++ packages/electron/package.json | 89 + packages/electron/preload.mjs | 143 ++ .../electron/resources/entitlements.mac.plist | 35 + .../electron/resources/icons/app-icon.png | Bin 0 -> 24006 bytes .../electron/resources/icons/app-icon.svg | 33 + .../electron/resources/icons/dev-icon.icns | Bin 0 -> 173094 bytes .../electron/resources/icons/dev-icon.png | Bin 0 -> 66751 bytes packages/electron/resources/icons/icon.icns | Bin 0 -> 160844 bytes packages/electron/resources/icons/icon.png | Bin 0 -> 55246 bytes .../electron/scripts/build-web-assets.mjs | 75 + packages/electron/scripts/bundle-main.mjs | 44 + packages/electron/scripts/electron-dev.mjs | 131 + .../electron/scripts/finalize-latest-yml.mjs | 113 + packages/electron/scripts/rebuild-native.mjs | 30 + packages/electron/ssh-manager.mjs | 1240 ++++++++++ packages/ui/src/App.tsx | 35 + packages/ui/src/components/chat/ChatInput.tsx | 2 +- .../ui/src/components/chat/ChatMessage.tsx | 2 +- .../chat/components/ScrollToBottomButton.tsx | 2 +- .../desktop/DesktopHostSwitcher.tsx | 8 + .../components/desktop/OpenInAppButton.tsx | 5 +- packages/ui/src/components/layout/Header.tsx | 11 +- .../components/multirun/MultiRunLauncher.tsx | 3 +- .../session/ProjectNotesTodoPanel.tsx | 109 +- .../src/components/session/SessionSidebar.tsx | 11 +- .../ui/src/components/views/FilesView.tsx | 51 +- packages/ui/src/components/views/GitView.tsx | 10 +- .../components/views/git/AIHighlightsBox.tsx | 7 +- .../components/views/git/BranchSelector.tsx | 6 + .../src/components/views/git/CommitInput.tsx | 33 +- .../components/views/git/CommitSection.tsx | 5 +- .../ui/src/contexts/ThemeSystemContext.tsx | 20 +- packages/ui/src/hooks/useMenuActions.ts | 44 +- packages/ui/src/hooks/useWindowTitle.ts | 15 +- packages/ui/src/lib/desktop.ts | 87 +- packages/ui/src/lib/desktopNative.ts | 162 ++ packages/ui/src/lib/device.ts | 14 +- packages/ui/src/lib/exportSession.ts | 6 +- packages/ui/src/lib/theme/cssGenerator.ts | 4 +- packages/ui/src/types/desktop.d.ts | 1 + packages/web/bin/cli.test.js | 2 +- packages/web/package.json | 83 +- packages/web/server/index.js | 3 + .../server/lib/event-stream/protocol.test.js | 2 +- .../server/lib/event-stream/runtime.test.js | 2 +- packages/web/server/lib/git/service.js | 6 +- .../lib/notifications/emitter-runtime.js | 28 +- .../server/lib/notifications/message.test.js | 2 +- .../lib/opencode/project-directory-runtime.js | 15 + .../lib/opencode/session-runtime.test.js | 2 +- .../lib/opencode/settings-helpers.test.js | 2 +- .../server/lib/opencode/settings-runtime.js | 19 +- packages/web/server/lib/package-manager.js | 16 + .../lib/projects/project-config.test.js | 2 +- .../lib/scheduled-tasks/runtime.test.js | 2 +- .../lib/terminal/output-replay-buffer.test.js | 2 +- .../lib/terminal/terminal-ws-protocol.test.js | 2 +- packages/web/server/opencode-proxy.test.js | 2 +- packages/web/server/proxy-headers.test.js | 2 +- scripts/bump-version.mjs | 1 + 68 files changed, 6100 insertions(+), 290 deletions(-) create mode 100644 docs/TAURI_TO_ELECTRON_CUTOVER.md create mode 100644 packages/electron/.gitignore create mode 100644 packages/electron/main.mjs create mode 100644 packages/electron/package.json create mode 100644 packages/electron/preload.mjs create mode 100644 packages/electron/resources/entitlements.mac.plist create mode 100644 packages/electron/resources/icons/app-icon.png create mode 100644 packages/electron/resources/icons/app-icon.svg create mode 100644 packages/electron/resources/icons/dev-icon.icns create mode 100644 packages/electron/resources/icons/dev-icon.png create mode 100644 packages/electron/resources/icons/icon.icns create mode 100644 packages/electron/resources/icons/icon.png create mode 100644 packages/electron/scripts/build-web-assets.mjs create mode 100644 packages/electron/scripts/bundle-main.mjs create mode 100644 packages/electron/scripts/electron-dev.mjs create mode 100644 packages/electron/scripts/finalize-latest-yml.mjs create mode 100644 packages/electron/scripts/rebuild-native.mjs create mode 100644 packages/electron/ssh-manager.mjs create mode 100644 packages/ui/src/lib/desktopNative.ts diff --git a/.github/workflows/build-macos-arm64-dmg.yml b/.github/workflows/build-macos-arm64-dmg.yml index 551ccca0..71aeaa04 100644 --- a/.github/workflows/build-macos-arm64-dmg.yml +++ b/.github/workflows/build-macos-arm64-dmg.yml @@ -123,3 +123,79 @@ jobs: name: dmg-${{ inputs.macos_version }}-arm64 path: artifacts/*.dmg retention-days: 7 + + build-macos-dmg-arm64-electron: + name: Build Electron DMG (arm64, ${{ inputs.macos_version }}) + runs-on: ${{ inputs.macos_version }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref || github.ref }} + + - name: Setup bun + uses: oven-sh/setup-bun@v2 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Install Apple Certificate + env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + run: | + KEYCHAIN_PATH=$RUNNER_TEMP/electron-signing.keychain-db + KEYCHAIN_PASSWORD=$(openssl rand -base64 32) + + security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" + security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + + echo "$APPLE_CERTIFICATE" | base64 --decode > $RUNNER_TEMP/certificate.p12 + security import $RUNNER_TEMP/certificate.p12 \ + -P "$APPLE_CERTIFICATE_PASSWORD" \ + -A -t cert -f pkcs12 \ + -k "$KEYCHAIN_PATH" + + security list-keychain -d user -s "$KEYCHAIN_PATH" + security set-key-partition-list -S apple-tool:,apple:,codesign: \ + -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + + - name: Build Electron app (arm64) + working-directory: packages/electron + env: + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + ELECTRON_BUILDER_ARCH: arm64 + run: | + bun run build:web-assets + bun run bundle:main + bun run rebuild:native + ./node_modules/.bin/electron-builder --mac --arm64 --publish=never + + - name: Prepare DMG artifact + run: | + set -euo pipefail + mkdir -p artifacts + DMG_PATH="packages/electron/dist/*.dmg" + if ls $DMG_PATH 1> /dev/null 2>&1; then + DMG_FILE=$(ls $DMG_PATH | head -n 1) + DMG_NAME="OpenChamber_Electron_${{ inputs.macos_version }}_arm64.dmg" + cp "$DMG_FILE" "artifacts/$DMG_NAME" + else + echo "Error: DMG file not found at $DMG_PATH" + exit 1 + fi + + - name: Upload DMG artifact + uses: actions/upload-artifact@v4 + with: + name: dmg-electron-${{ inputs.macos_version }}-arm64 + path: artifacts/*.dmg + retention-days: 7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e4688e7f..b1865b18 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -494,8 +494,170 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + build-desktop-electron-macos: + needs: create-release + runs-on: macos-26 + strategy: + fail-fast: false + matrix: + include: + - target: aarch64-apple-darwin + arch: arm64 + platform: darwin-aarch64 + - target: x86_64-apple-darwin + arch: x64 + platform: darwin-x86_64 + steps: + - uses: actions/checkout@v4 + + - name: Setup bun + uses: oven-sh/setup-bun@v2 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Install Apple Certificate + env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + run: | + KEYCHAIN_PATH=$RUNNER_TEMP/electron-signing.keychain-db + KEYCHAIN_PASSWORD=$(openssl rand -base64 32) + + security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" + security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + + echo "$APPLE_CERTIFICATE" | base64 --decode > $RUNNER_TEMP/certificate.p12 + security import $RUNNER_TEMP/certificate.p12 \ + -P "$APPLE_CERTIFICATE_PASSWORD" \ + -A -t cert -f pkcs12 \ + -k "$KEYCHAIN_PATH" + + security list-keychain -d user -s "$KEYCHAIN_PATH" + security set-key-partition-list -S apple-tool:,apple:,codesign: \ + -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + + - name: Build Electron app + working-directory: packages/electron + env: + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + # rebuild-native.mjs reads this to target the right arch when + # cross-building (runner is arm64; x64 matrix needs the hint). + ELECTRON_BUILDER_ARCH: ${{ matrix.arch }} + run: | + bun run build:web-assets + bun run bundle:main + # npmRebuild=false in package.json, so electron-builder won't + # recompile native deps on its own — we must rebuild against the + # target Electron ABI before packaging, otherwise better-sqlite3/ + # node-pty/bun-pty crash on require inside the packaged app. + bun run rebuild:native + ./node_modules/.bin/electron-builder --mac --${{ matrix.arch }} --publish=never + + - name: Verify signature + entitlements + notarization + run: | + set -euo pipefail + + APP_DIR="packages/electron/dist/mac" + [ -d "packages/electron/dist/mac-arm64" ] && APP_DIR="packages/electron/dist/mac-arm64" + + APP_PATH=$(find "$APP_DIR" -maxdepth 2 -name "*.app" -print -quit) + if [ -z "$APP_PATH" ]; then + echo "Error: .app not found under packages/electron/dist/mac*" + ls -la packages/electron/dist/ + exit 1 + fi + + echo "Verifying $APP_PATH" + codesign -vv --deep --strict "$APP_PATH" + + # Require hardened runtime + CS_INFO=$(codesign -dv --verbose=4 "$APP_PATH" 2>&1) + echo "$CS_INFO" + if ! echo "$CS_INFO" | grep -q "flags=.*runtime"; then + echo "Error: hardened runtime flag missing" + exit 1 + fi + + # Require notary ticket stapled + xcrun stapler validate "$APP_PATH" + + ENTITLEMENTS=$(codesign -d --entitlements :- "$APP_PATH" 2>&1 || true) + if echo "$ENTITLEMENTS" | grep -q "com.apple.security.app-sandbox"; then + echo "Error: app sandbox entitlement is present" + exit 1 + fi + for key in \ + com.apple.security.cs.allow-jit \ + com.apple.security.cs.allow-unsigned-executable-memory \ + com.apple.security.cs.disable-library-validation + do + if ! echo "$ENTITLEMENTS" | grep -q "$key"; then + echo "Error: required entitlement missing: $key" + exit 1 + fi + done + + - name: Upload DMG / ZIP / blockmaps to release + uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ needs.create-release.outputs.version }} + files: | + packages/electron/dist/*.dmg + packages/electron/dist/*.zip + packages/electron/dist/*.blockmap + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload per-arch latest-mac.yml for merge + uses: actions/upload-artifact@v4 + with: + name: latest-yml-${{ matrix.target }} + path: packages/electron/dist/latest-mac.yml + retention-days: 1 + + combine-electron-manifests: + needs: [create-release, build-desktop-electron-macos] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Download per-arch latest-mac.yml + uses: actions/download-artifact@v4 + with: + pattern: latest-yml-*-apple-darwin + path: artifacts + + - name: Finalize combined latest-mac.yml + env: + LATEST_YML_DIR: ${{ github.workspace }}/artifacts + GH_REPO: ${{ github.repository }} + OPENCHAMBER_VERSION: ${{ needs.create-release.outputs.version }} + run: node packages/electron/scripts/finalize-latest-yml.mjs + + - name: Upload combined latest-mac.yml to release + uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ needs.create-release.outputs.version }} + files: ${{ runner.temp }}/latest-mac.yml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + finalize-release: - needs: [create-release, build-desktop-macos, publish-npm, combine-manifests] + needs: [create-release, build-desktop-macos, build-desktop-electron-macos, publish-npm, combine-manifests, combine-electron-manifests] runs-on: ubuntu-latest env: DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} diff --git a/AGENTS.md b/AGENTS.md index 880a054f..174812e0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,9 +6,19 @@ OpenChamber provides UI runtimes (web/desktop/VS Code) for interacting with an O ## Runtime architecture (IMPORTANT) -- `Desktop` is a thin Tauri shell that starts the web server sidecar and loads the web UI from `http://127.0.0.1:`. -- All backend logic lives in `packages/web/server/*` (and `packages/vscode/*` for the VS Code runtime). Desktop Rust is not a feature backend. -- Tauri is used only for stable native integrations: menu, dialog (open folder), notifications, updater, deep-links. +- `Desktop` (Electron) boots the web server **in the same Node process** as the Electron main, then loads the web UI from `http://127.0.0.1:`. No sidecar subprocess. +- `Desktop` (Tauri, legacy) still spawns `openchamber-server` as a bun-compiled sidecar binary. Kept only for auto-update compatibility with existing Tauri installs. +- All backend logic lives in `packages/web/server/*` (and `packages/vscode/*` for the VS Code runtime). The native shell is not a feature backend. +- The shell is used only for stable native integrations: menu, dialog (open folder), notifications, updater, deep-links, quit confirmation. + +### Desktop shell: Electron is the target, Tauri is legacy + +- **New desktop work goes into `packages/electron/`.** This is the forward path. +- `packages/desktop/` (Tauri) is kept running in parallel only to preserve auto-update for existing installs until the cutover. Do **not** add features to it; do **not** port bug fixes back unless they actually affect currently-released Tauri users. +- Desktop-side changes (IPC handlers, native integrations, window/quit/notification behavior) land in `packages/electron/main.mjs` + `packages/electron/preload.mjs`. The `__TAURI__` shim exposed by the preload keeps the shared UI working against both shells, so renderer-side code should not branch on shell type. +- Electron imports the server via `@openchamber/web/server/index.js` (workspace dep) and calls `startWebUiServer({...})`. The returned handle has `getPort()` / `stop()`. Notifications flow via an `onDesktopNotification` callback injected at startup — no stdout-parsing IPC. +- Build/release: both shells ship in the same GitHub release today (`.github/workflows/release.yml`). The one-shot Tauri → Electron auto-update migration is documented in `docs/TAURI_TO_ELECTRON_CUTOVER.md`; run that when the user decides to flip. +- After the cutover ships and stabilises, `packages/desktop/` is deleted; this note collapses back to "Desktop is Electron". ## Tech stack (source of truth: `package.json`, resolved: `bun.lock`) @@ -17,7 +27,8 @@ OpenChamber provides UI runtimes (web/desktop/VS Code) for interacting with an O - State: Zustand (`packages/ui/src/stores/`) - UI primitives: Base UI (`@base-ui/react`, primary source for dropdown/select/dialog/menu/tooltip/etc. — wrappers live in `packages/ui/src/components/ui/`), Radix UI (`package.json` deps, legacy usages being migrated), HeroUI (`package.json` deps), Remixicon (`package.json` deps) - Server: Express (`packages/web/server/index.js`) -- Desktop: Tauri v2 (`packages/desktop/src-tauri/`) +- Desktop (forward): Electron 41 (`packages/electron/`) +- Desktop (legacy, maintenance-only): Tauri v2 (`packages/desktop/src-tauri/`) - VS Code: extension + webview (`packages/vscode/`) ## Monorepo layout @@ -26,7 +37,8 @@ Workspaces are `packages/*` (see `package.json`). - Shared UI: `packages/ui` - Web app + server + CLI: `packages/web` -- Desktop app (Tauri): `packages/desktop` +- Desktop shell (Electron — forward): `packages/electron` +- Desktop shell (Tauri — legacy, maintenance-only): `packages/desktop` - VS Code extension: `packages/vscode` ## Documentation map @@ -95,7 +107,9 @@ All scripts are in `package.json`. - Validate: `bun run type-check`, `bun run lint` - Build all: `bun run build` -- Desktop build: `bun run desktop:build` +- Desktop build (Electron — primary): `bun run electron:build` +- Desktop dev (Electron): `bun run electron:dev` +- Desktop build (Tauri — legacy): `bun run desktop:build` - VS Code build: `bun run vscode:build` - Release smoke build: `bun run release:test` (shell script: `scripts/test-release-build.sh`) @@ -104,8 +118,8 @@ All scripts are in `package.json`. - Web bootstrap: `packages/web/src/main.tsx` - Web server: `packages/web/server/index.js` - Web CLI: `packages/web/bin/cli.js` (package bin: `packages/web/package.json`) -- Desktop: Tauri entry `packages/desktop/src-tauri/src/main.rs` (spawns web server sidecar + loads web UI) -- Tauri backend: `packages/desktop/src-tauri/src/main.rs` +- Desktop (Electron — primary): `packages/electron/main.mjs` (boots the web server in-process via `startWebUiServer`, loads web UI over loopback; preload at `packages/electron/preload.mjs` exposes the `__TAURI__` IPC shim so shared UI code is shell-agnostic) +- Desktop (Tauri — legacy): `packages/desktop/src-tauri/src/main.rs` - VS Code extension host: `packages/vscode/src/extension.ts` - VS Code webview bootstrap: `packages/vscode/webview/main.tsx` diff --git a/bun.lock b/bun.lock index 750637ed..0c009676 100644 --- a/bun.lock +++ b/bun.lock @@ -102,6 +102,21 @@ "typescript": "~5.8.3", }, }, + "packages/electron": { + "name": "@openchamber/electron", + "version": "1.9.6", + "dependencies": { + "@openchamber/web": "workspace:*", + "electron-context-menu": "^4.1.2", + "electron-log": "^5.4.3", + "electron-updater": "^6.8.3", + }, + "devDependencies": { + "@electron/rebuild": "^3.7.0", + "electron": "^41.2.1", + "electron-builder": "^26.0.0", + }, + }, "packages/ui": { "name": "@openchamber/ui", "version": "1.9.6", @@ -231,15 +246,37 @@ "openchamber": "./bin/cli.js", }, "dependencies": { - "@base-ui/react": "^1.4.0", "@clack/prompts": "^1.1.0", + "@octokit/rest": "^22.0.1", + "@opencode-ai/sdk": "^1.4.6", + "@simplewebauthn/server": "13.3.0", + "adm-zip": "^0.5.16", + "better-sqlite3": "^11.7.0", + "bun-pty": "^0.4.5", + "compression": "^1.8.1", + "cron-parser": "^4.9.0", + "express": "^5.1.0", + "http-proxy-middleware": "^3.0.5", + "jose": "^6.1.3", + "jsonc-parser": "^3.3.1", + "luxon": "^3.5.0", + "node-pty": "1.2.0-beta.12", + "openai": "^4.79.0", + "qrcode-terminal": "^0.12.0", + "reflect-metadata": "^0.2.2", + "simple-git": "^3.28.0", + "web-push": "^3.6.7", + "ws": "^8.18.3", + "yaml": "^2.8.1", + }, + "devDependencies": { + "@base-ui/react": "^1.4.0", "@codemirror/lang-cpp": "^6.0.3", "@codemirror/lang-go": "^6.0.1", + "@eslint/js": "^9.33.0", "@fontsource/ibm-plex-mono": "^5.2.7", "@fontsource/ibm-plex-sans": "^5.1.1", "@ibm/plex": "^6.4.1", - "@octokit/rest": "^22.0.1", - "@opencode-ai/sdk": "^1.4.6", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", @@ -251,57 +288,35 @@ "@radix-ui/react-tooltip": "^1.2.8", "@remixicon/react": "^4.7.0", "@simplewebauthn/browser": "13.3.0", - "@simplewebauthn/server": "13.3.0", - "@types/react-syntax-highlighter": "^15.5.13", - "adm-zip": "^0.5.16", - "bun-pty": "^0.4.5", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "cmdk": "^1.1.1", - "compression": "^1.8.1", - "cron-parser": "^4.9.0", - "express": "^5.1.0", - "ghostty-web": "0.3.0", - "http-proxy-middleware": "^3.0.5", - "jose": "^6.1.3", - "jsonc-parser": "^3.3.1", - "luxon": "^3.5.0", - "next-themes": "^0.4.6", - "node-pty": "1.2.0-beta.12", - "openai": "^4.79.0", - "qrcode-terminal": "^0.12.0", - "react": "^19.1.1", - "react-dom": "^19.1.1", - "react-markdown": "^10.1.0", - "react-syntax-highlighter": "^15.6.6", - "reflect-metadata": "^0.2.2", - "remark-gfm": "^4.0.1", - "simple-git": "^3.28.0", - "sonner": "^2.0.7", - "strip-json-comments": "^5.0.3", - "tailwind-merge": "^3.3.1", - "web-push": "^3.6.7", - "ws": "^8.18.3", - "yaml": "^2.8.1", - "zustand": "^5.0.8", - }, - "devDependencies": { - "@eslint/js": "^9.33.0", "@tailwindcss/postcss": "^4.0.0", "@types/adm-zip": "^0.5.7", "@types/node": "^24.3.1", "@types/react": "^19.1.10", "@types/react-dom": "^19.1.7", + "@types/react-syntax-highlighter": "^15.5.13", "@vitejs/plugin-react": "^5.0.0", "autoprefixer": "^10.4.21", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "cmdk": "^1.1.1", "concurrently": "^9.2.1", "cors": "^2.8.5", "cross-env": "^7.0.3", "eslint": "^9.33.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", + "ghostty-web": "0.3.0", "globals": "^16.3.0", + "next-themes": "^0.4.6", "nodemon": "^3.1.7", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-markdown": "^10.1.0", + "react-syntax-highlighter": "^15.6.6", + "remark-gfm": "^4.0.1", + "sonner": "^2.0.7", + "strip-json-comments": "^5.0.3", + "tailwind-merge": "^3.3.1", "tailwindcss": "^4.0.0", "tsx": "^4.20.6", "tw-animate-css": "^1.3.8", @@ -309,7 +324,9 @@ "typescript-eslint": "^8.39.1", "vite": "^7.1.2", "vite-plugin-pwa": "^1.0.3", + "vitest": "^3.0.5", "workbox-window": "^7.4.0", + "zustand": "^5.0.8", }, }, }, @@ -318,6 +335,8 @@ "@codemirror/view": "6.39.13", }, "packages": { + "7zip-bin": ["7zip-bin@5.2.0", "", {}, "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A=="], + "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], "@apideck/better-ajv-errors": ["@apideck/better-ajv-errors@0.3.6", "", { "dependencies": { "json-schema": "^0.4.0", "jsonpointer": "^5.0.0", "leven": "^3.1.0" }, "peerDependencies": { "ajv": ">=8" } }, "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA=="], @@ -602,6 +621,8 @@ "@date-fns/tz": ["@date-fns/tz@1.4.1", "", {}, "sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA=="], + "@develar/schema-utils": ["@develar/schema-utils@2.6.5", "", { "dependencies": { "ajv": "^6.12.0", "ajv-keywords": "^3.4.1" } }, "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig=="], + "@dnd-kit/accessibility": ["@dnd-kit/accessibility@3.1.1", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw=="], "@dnd-kit/core": ["@dnd-kit/core@6.3.1", "", { "dependencies": { "@dnd-kit/accessibility": "^3.1.1", "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ=="], @@ -610,6 +631,24 @@ "@dnd-kit/utilities": ["@dnd-kit/utilities@3.2.2", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg=="], + "@electron/asar": ["@electron/asar@3.4.1", "", { "dependencies": { "commander": "^5.0.0", "glob": "^7.1.6", "minimatch": "^3.0.4" }, "bin": { "asar": "bin/asar.js" } }, "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA=="], + + "@electron/fuses": ["@electron/fuses@1.8.0", "", { "dependencies": { "chalk": "^4.1.1", "fs-extra": "^9.0.1", "minimist": "^1.2.5" }, "bin": { "electron-fuses": "dist/bin.js" } }, "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw=="], + + "@electron/get": ["@electron/get@2.0.3", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], + + "@electron/node-gyp": ["@electron/node-gyp@github:electron/node-gyp#06b29aa", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "glob": "^8.1.0", "graceful-fs": "^4.2.6", "make-fetch-happen": "^10.2.1", "nopt": "^6.0.0", "proc-log": "^2.0.1", "semver": "^7.3.5", "tar": "^6.2.1", "which": "^2.0.2" }, "bin": "./bin/node-gyp.js" }, "electron-node-gyp-06b29aa"], + + "@electron/notarize": ["@electron/notarize@2.5.0", "", { "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.1", "promise-retry": "^2.0.1" } }, "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A=="], + + "@electron/osx-sign": ["@electron/osx-sign@1.3.3", "", { "dependencies": { "compare-version": "^0.1.2", "debug": "^4.3.4", "fs-extra": "^10.0.0", "isbinaryfile": "^4.0.8", "minimist": "^1.2.6", "plist": "^3.0.5" }, "bin": { "electron-osx-flat": "bin/electron-osx-flat.js", "electron-osx-sign": "bin/electron-osx-sign.js" } }, "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg=="], + + "@electron/rebuild": ["@electron/rebuild@3.7.2", "", { "dependencies": { "@electron/node-gyp": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", "@malept/cross-spawn-promise": "^2.0.0", "chalk": "^4.0.0", "debug": "^4.1.1", "detect-libc": "^2.0.1", "fs-extra": "^10.0.0", "got": "^11.7.0", "node-abi": "^3.45.0", "node-api-version": "^0.2.0", "ora": "^5.1.0", "read-binary-file-arch": "^1.0.6", "semver": "^7.3.5", "tar": "^6.0.5", "yargs": "^17.0.1" }, "bin": { "electron-rebuild": "lib/cli.js" } }, "sha512-19/KbIR/DAxbsCkiaGMXIdPnMCJLkcf8AvGnduJtWBs/CBwiAjY1apCqOLVxrXg+rtXFCngbXhBanWjxLUt1Mg=="], + + "@electron/universal": ["@electron/universal@2.0.3", "", { "dependencies": { "@electron/asar": "^3.3.1", "@malept/cross-spawn-promise": "^2.0.0", "debug": "^4.3.1", "dir-compare": "^4.2.0", "fs-extra": "^11.1.1", "minimatch": "^9.0.3", "plist": "^3.1.0" } }, "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g=="], + + "@electron/windows-sign": ["@electron/windows-sign@1.2.2", "", { "dependencies": { "cross-dirname": "^0.1.0", "debug": "^4.3.4", "fs-extra": "^11.1.1", "minimist": "^1.2.8", "postject": "^1.0.0-alpha.6" }, "bin": { "electron-windows-sign": "bin/electron-windows-sign.js" } }, "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.24.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA=="], "@esbuild/android-arm": ["@esbuild/android-arm@0.24.2", "", { "os": "android", "cpu": "arm" }, "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q=="], @@ -702,6 +741,8 @@ "@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.6.2", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA=="], + "@gar/promisify": ["@gar/promisify@1.1.3", "", {}, "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw=="], + "@heroui/react-rsc-utils": ["@heroui/react-rsc-utils@2.1.9", "", { "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0" } }, "sha512-e77OEjNCmQxE9/pnLDDb93qWkX58/CcgIqdNAczT/zUP+a48NxGq2A2WRimvc1uviwaNL2StriE2DmyZPyYW7Q=="], "@heroui/react-utils": ["@heroui/react-utils@2.1.14", "", { "dependencies": { "@heroui/react-rsc-utils": "2.1.9", "@heroui/shared-utils": "2.1.12" }, "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0" } }, "sha512-hhKklYKy9sRH52C9A8P0jWQ79W4MkIvOnKBIuxEMHhigjfracy0o0lMnAUdEsJni4oZKVJYqNGdQl+UVgcmeDA=="], @@ -742,6 +783,8 @@ "@isaacs/cliui": ["@isaacs/cliui@9.0.0", "", {}, "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg=="], + "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], @@ -794,6 +837,10 @@ "@lezer/yaml": ["@lezer/yaml@1.0.4", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.4.0" } }, "sha512-2lrrHqxalACEbxIbsjhqGpSW8kWpUKuY6RHgnSAFZa6qK62wvnPxA8hGOwOoDbwHcOFs5M4o27mjGu+P7TvBmw=="], + "@malept/cross-spawn-promise": ["@malept/cross-spawn-promise@2.0.0", "", { "dependencies": { "cross-spawn": "^7.0.1" } }, "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg=="], + + "@malept/flatpak-bundler": ["@malept/flatpak-bundler@0.4.0", "", { "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.0", "lodash": "^4.17.15", "tmp-promise": "^3.0.2" } }, "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q=="], + "@marijn/find-cluster-break": ["@marijn/find-cluster-break@1.0.2", "", {}, "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g=="], "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], @@ -802,6 +849,12 @@ "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + "@npmcli/agent": ["@npmcli/agent@3.0.0", "", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^10.0.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q=="], + + "@npmcli/fs": ["@npmcli/fs@2.1.2", "", { "dependencies": { "@gar/promisify": "^1.1.3", "semver": "^7.3.5" } }, "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ=="], + + "@npmcli/move-file": ["@npmcli/move-file@2.0.1", "", { "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" } }, "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ=="], + "@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="], "@octokit/core": ["@octokit/core@7.0.6", "", { "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", "@octokit/request": "^10.0.6", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q=="], @@ -828,6 +881,8 @@ "@openchamber/desktop": ["@openchamber/desktop@workspace:packages/desktop"], + "@openchamber/electron": ["@openchamber/electron@workspace:packages/electron"], + "@openchamber/ui": ["@openchamber/ui@workspace:packages/ui"], "@openchamber/web": ["@openchamber/web@workspace:packages/web"], @@ -860,6 +915,8 @@ "@pierre/diffs": ["@pierre/diffs@1.1.0-beta.13", "", { "dependencies": { "@shikijs/transformers": "^3.0.0", "diff": "8.0.3", "hast-util-to-html": "9.0.5", "lru_map": "0.4.1", "shiki": "^3.0.0" }, "peerDependencies": { "react": "^18.3.1 || ^19.0.0", "react-dom": "^18.3.1 || ^19.0.0" } }, "sha512-D35rxDu5V7XHX5aVGU6PF12GhscL+I+9QYgxK/i3h0d2XSirAxDdVNm49aYwlOhgmdvL0NbS1IHxPswVB5yJvw=="], + "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], + "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="], "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], @@ -1066,12 +1123,16 @@ "@simplewebauthn/server": ["@simplewebauthn/server@13.3.0", "", { "dependencies": { "@hexagon/base64": "^1.1.27", "@levischuck/tiny-cbor": "^0.2.2", "@peculiar/asn1-android": "^2.6.0", "@peculiar/asn1-ecc": "^2.6.1", "@peculiar/asn1-rsa": "^2.6.1", "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "@peculiar/x509": "^1.14.3" } }, "sha512-MLHYFrYG8/wK2i+86XMhiecK72nMaHKKt4bo+7Q1TbuG9iGjlSdfkPWKO5ZFE/BX+ygCJ7pr8H/AJeyAj1EaTQ=="], + "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], + "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@2.3.0", "", {}, "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg=="], "@surma/rollup-plugin-off-main-thread": ["@surma/rollup-plugin-off-main-thread@2.2.3", "", { "dependencies": { "ejs": "^3.1.6", "json5": "^2.2.0", "magic-string": "^0.25.0", "string.prototype.matchall": "^4.0.6" } }, "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ=="], "@swc/helpers": ["@swc/helpers@0.5.19", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-QamiFeIK3txNjgUTNppE6MiG3p7TdninpZu0E0PbqVh1a9FNLT2FRhisaa4NcaX52XVhA5l7Pk58Ft7Sqi/2sA=="], + "@szmarczak/http-timer": ["@szmarczak/http-timer@4.0.6", "", { "dependencies": { "defer-to-connect": "^2.0.0" } }, "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w=="], + "@tailwindcss/node": ["@tailwindcss/node@4.2.1", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", "lightningcss": "1.31.1", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.2.1" } }, "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg=="], "@tailwindcss/oxide": ["@tailwindcss/oxide@4.2.1", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.2.1", "@tailwindcss/oxide-darwin-arm64": "4.2.1", "@tailwindcss/oxide-darwin-x64": "4.2.1", "@tailwindcss/oxide-freebsd-x64": "4.2.1", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", "@tailwindcss/oxide-linux-x64-musl": "4.2.1", "@tailwindcss/oxide-wasm32-wasi": "4.2.1", "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" } }, "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw=="], @@ -1142,6 +1203,8 @@ "@textlint/types": ["@textlint/types@15.5.2", "", { "dependencies": { "@textlint/ast-node-types": "15.5.2" } }, "sha512-sJOrlVLLXp4/EZtiWKWq9y2fWyZlI8GP+24rnU5avtPWBIMm/1w97yzKrAqYF8czx2MqR391z5akhnfhj2f/AQ=="], + "@tootallnate/once": ["@tootallnate/once@2.0.0", "", {}, "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A=="], + "@types/adm-zip": ["@types/adm-zip@0.5.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-DNEs/QvmyRLurdQPChqq0Md4zGvPwHerAJYWk9l2jCbD1VPpnzRJorOdiq4zsw09NFbYnhfsoEhWtxIzXpn2yw=="], "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], @@ -1152,22 +1215,34 @@ "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], + "@types/cacheable-request": ["@types/cacheable-request@6.0.3", "", { "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", "@types/node": "*", "@types/responselike": "^1.0.0" } }, "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw=="], + + "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], + "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], + "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], + "@types/dom-speech-recognition": ["@types/dom-speech-recognition@0.0.7", "", {}, "sha512-NjiUoJbBlKhyufNsMZLSp+pbPNtPAFnR738RCJvtZy/HVQ2TZjmqpMyaeOSMXgxdfZM60nt8QGbtfmQrJAH2sw=="], "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], + "@types/fs-extra": ["@types/fs-extra@9.0.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA=="], + "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], + "@types/http-cache-semantics": ["@types/http-cache-semantics@4.2.0", "", {}, "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q=="], + "@types/http-proxy": ["@types/http-proxy@1.17.17", "", { "dependencies": { "@types/node": "*" } }, "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw=="], "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], "@types/katex": ["@types/katex@0.16.8", "", {}, "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg=="], + "@types/keyv": ["@types/keyv@3.1.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg=="], + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], @@ -1178,6 +1253,8 @@ "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], + "@types/plist": ["@types/plist@3.0.5", "", { "dependencies": { "@types/node": "*", "xmlbuilder": ">=11.0.1" } }, "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA=="], + "@types/prismjs": ["@types/prismjs@1.26.6", "", {}, "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw=="], "@types/qrcode": ["@types/qrcode@1.5.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw=="], @@ -1190,14 +1267,20 @@ "@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="], + "@types/responselike": ["@types/responselike@1.0.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw=="], + "@types/sarif": ["@types/sarif@2.1.7", "", {}, "sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ=="], "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + "@types/verror": ["@types/verror@1.10.11", "", {}, "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg=="], + "@types/vscode": ["@types/vscode@1.109.0", "", {}, "sha512-0Pf95rnwEIwDbmXGC08r0B4TQhAbsHQ5UyTIgVgoieDe4cOnf92usuR5dEczb6bTKEp7ziZH4TV1TRGPPCExtw=="], + "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.56.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/type-utils": "8.56.1", "@typescript-eslint/utils": "8.56.1", "@typescript-eslint/visitor-keys": "8.56.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.56.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A=="], "@typescript-eslint/parser": ["@typescript-eslint/parser@8.56.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/types": "8.56.1", "@typescript-eslint/typescript-estree": "8.56.1", "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg=="], @@ -1224,6 +1307,20 @@ "@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.4", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA=="], + "@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="], + + "@vitest/mocker": ["@vitest/mocker@3.2.4", "", { "dependencies": { "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ=="], + + "@vitest/pretty-format": ["@vitest/pretty-format@3.2.4", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA=="], + + "@vitest/runner": ["@vitest/runner@3.2.4", "", { "dependencies": { "@vitest/utils": "3.2.4", "pathe": "^2.0.3", "strip-literal": "^3.0.0" } }, "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ=="], + + "@vitest/snapshot": ["@vitest/snapshot@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ=="], + + "@vitest/spy": ["@vitest/spy@3.2.4", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw=="], + + "@vitest/utils": ["@vitest/utils@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA=="], + "@vscode/vsce": ["@vscode/vsce@3.7.1", "", { "dependencies": { "@azure/identity": "^4.1.0", "@secretlint/node": "^10.1.2", "@secretlint/secretlint-formatter-sarif": "^10.1.2", "@secretlint/secretlint-rule-no-dotenv": "^10.1.2", "@secretlint/secretlint-rule-preset-recommend": "^10.1.2", "@vscode/vsce-sign": "^2.0.0", "azure-devops-node-api": "^12.5.0", "chalk": "^4.1.2", "cheerio": "^1.0.0-rc.9", "cockatiel": "^3.1.2", "commander": "^12.1.0", "form-data": "^4.0.0", "glob": "^11.0.0", "hosted-git-info": "^4.0.2", "jsonc-parser": "^3.2.0", "leven": "^3.1.0", "markdown-it": "^14.1.0", "mime": "^1.3.4", "minimatch": "^3.0.3", "parse-semver": "^1.1.1", "read": "^1.0.7", "secretlint": "^10.1.2", "semver": "^7.5.2", "tmp": "^0.2.3", "typed-rest-client": "^1.8.4", "url-join": "^4.0.1", "xml2js": "^0.5.0", "yauzl": "^2.3.1", "yazl": "^2.2.2" }, "optionalDependencies": { "keytar": "^7.7.0" }, "bin": { "vsce": "vsce" } }, "sha512-OTm2XdMt2YkpSn2Nx7z2EJtSuhRHsTPYsSK59hr3v8jRArK+2UEoju4Jumn1CmpgoBLGI6ReHLJ/czYltNUW3g=="], "@vscode/vsce-sign": ["@vscode/vsce-sign@2.0.9", "", { "optionalDependencies": { "@vscode/vsce-sign-alpine-arm64": "2.0.6", "@vscode/vsce-sign-alpine-x64": "2.0.6", "@vscode/vsce-sign-darwin-arm64": "2.0.6", "@vscode/vsce-sign-darwin-x64": "2.0.6", "@vscode/vsce-sign-linux-arm": "2.0.6", "@vscode/vsce-sign-linux-arm64": "2.0.6", "@vscode/vsce-sign-linux-x64": "2.0.6", "@vscode/vsce-sign-win32-arm64": "2.0.6", "@vscode/vsce-sign-win32-x64": "2.0.6" } }, "sha512-8IvaRvtFyzUnGGl3f5+1Cnor3LqaUWvhaUjAYO8Y39OUYlOf3cRd+dowuQYLpZcP3uwSG+mURwjEBOSq4SOJ0g=="], @@ -1246,8 +1343,12 @@ "@vscode/vsce-sign-win32-x64": ["@vscode/vsce-sign-win32-x64@2.0.6", "", { "os": "win32", "cpu": "x64" }, "sha512-mgth9Kvze+u8CruYMmhHw6Zgy3GRX2S+Ed5oSokDEK5vPEwGGKnmuXua9tmFhomeAnhgJnL4DCna3TiNuGrBTQ=="], + "@xmldom/xmldom": ["@xmldom/xmldom@0.8.13", "", {}, "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw=="], + "@yarnpkg/lockfile": ["@yarnpkg/lockfile@1.1.0", "", {}, "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ=="], + "abbrev": ["abbrev@1.1.1", "", {}, "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="], + "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="], "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], @@ -1262,8 +1363,12 @@ "agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="], + "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], + "ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], + "ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], + "ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="], "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], @@ -1272,6 +1377,10 @@ "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], + "app-builder-bin": ["app-builder-bin@5.0.0-alpha.12", "", {}, "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w=="], + + "app-builder-lib": ["app-builder-lib@26.8.1", "", { "dependencies": { "@develar/schema-utils": "~2.6.5", "@electron/asar": "3.4.1", "@electron/fuses": "^1.8.0", "@electron/get": "^3.0.0", "@electron/notarize": "2.5.0", "@electron/osx-sign": "1.3.3", "@electron/rebuild": "^4.0.3", "@electron/universal": "2.0.3", "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", "async-exit-hook": "^2.0.1", "builder-util": "26.8.1", "builder-util-runtime": "9.5.1", "chromium-pickle-js": "^0.2.0", "ci-info": "4.3.1", "debug": "^4.3.4", "dotenv": "^16.4.5", "dotenv-expand": "^11.0.6", "ejs": "^3.1.8", "electron-publish": "26.8.1", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", "isbinaryfile": "^5.0.0", "jiti": "^2.4.2", "js-yaml": "^4.1.0", "json5": "^2.2.3", "lazy-val": "^1.0.5", "minimatch": "^10.0.3", "plist": "3.1.0", "proper-lockfile": "^4.1.2", "resedit": "^1.7.0", "semver": "~7.7.3", "tar": "^7.5.7", "temp-file": "^3.4.0", "tiny-async-pool": "1.3.0", "which": "^5.0.0" }, "peerDependencies": { "dmg-builder": "26.8.1", "electron-builder-squirrel-windows": "26.8.1" } }, "sha512-p0Im/Dx5C4tmz8QEE1Yn4MkuPC8PrnlRneMhWJj7BBXQfNTJUshM/bp3lusdEsDbvvfJZpXWnYesgSLvwtM2Zw=="], + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], @@ -1284,10 +1393,16 @@ "asn1js": ["asn1js@3.0.7", "", { "dependencies": { "pvtsutils": "^1.3.6", "pvutils": "^1.1.3", "tslib": "^2.8.1" } }, "sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ=="], + "assert-plus": ["assert-plus@1.0.0", "", {}, "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw=="], + + "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + "astral-regex": ["astral-regex@2.0.0", "", {}, "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="], "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], + "async-exit-hook": ["async-exit-hook@2.0.1", "", {}, "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw=="], + "async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="], "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], @@ -1320,10 +1435,14 @@ "before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], + "better-sqlite3": ["better-sqlite3@11.10.0", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ=="], + "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], "binaryextensions": ["binaryextensions@6.11.0", "", { "dependencies": { "editions": "^6.21.0" } }, "sha512-sXnYK/Ij80TO3lcqZVV2YgfKN5QjUWIRk/XSm2J/4bd/lPko3lvk0O4ZppH6m+6hB2/GTu+ptNwVFe1xh+QLQw=="], + "bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="], + "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], "bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="], @@ -1332,6 +1451,8 @@ "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], + "boolean": ["boolean@3.2.0", "", {}, "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="], + "boundary": ["boundary@2.0.0", "", {}, "sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA=="], "brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], @@ -1348,12 +1469,24 @@ "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], + "builder-util": ["builder-util@26.8.1", "", { "dependencies": { "7zip-bin": "~5.2.0", "@types/debug": "^4.1.6", "app-builder-bin": "5.0.0-alpha.12", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "cross-spawn": "^7.0.6", "debug": "^4.3.4", "fs-extra": "^10.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "js-yaml": "^4.1.0", "sanitize-filename": "^1.6.3", "source-map-support": "^0.5.19", "stat-mode": "^1.0.0", "temp-file": "^3.4.0", "tiny-async-pool": "1.3.0" } }, "sha512-pm1lTYbGyc90DHgCDO7eo8Rl4EqKLciayNbZqGziqnH9jrlKe8ZANGdityLZU+pJh16dfzjAx2xQq9McuIPEtw=="], + + "builder-util-runtime": ["builder-util-runtime@9.5.1", "", { "dependencies": { "debug": "^4.3.4", "sax": "^1.2.4" } }, "sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ=="], + "bun-pty": ["bun-pty@0.4.8", "", {}, "sha512-rO70Mrbr13+jxHHHu2YBkk2pNqrJE5cJn29WE++PUr+GFA0hq/VgtQPZANJ8dJo6d7XImvBk37Innt8GM7O28w=="], "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], + "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], + + "cacache": ["cacache@16.1.3", "", { "dependencies": { "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^2.0.0", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^8.0.1", "infer-owner": "^1.0.4", "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "mkdirp": "^1.0.4", "p-map": "^4.0.0", "promise-inflight": "^1.0.1", "rimraf": "^3.0.2", "ssri": "^9.0.0", "tar": "^6.1.11", "unique-filename": "^2.0.0" } }, "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ=="], + + "cacheable-lookup": ["cacheable-lookup@5.0.4", "", {}, "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="], + + "cacheable-request": ["cacheable-request@7.0.4", "", { "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^6.0.1", "responselike": "^2.0.0" } }, "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg=="], + "call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="], "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], @@ -1368,6 +1501,8 @@ "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], + "chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="], + "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], "character-entities": ["character-entities@1.2.4", "", {}, "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw=="], @@ -1378,20 +1513,36 @@ "character-reference-invalid": ["character-reference-invalid@1.1.4", "", {}, "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg=="], + "check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="], + "cheerio": ["cheerio@1.2.0", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "encoding-sniffer": "^0.2.1", "htmlparser2": "^10.1.0", "parse5": "^7.3.0", "parse5-htmlparser2-tree-adapter": "^7.1.0", "parse5-parser-stream": "^7.1.2", "undici": "^7.19.0", "whatwg-mimetype": "^4.0.0" } }, "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg=="], "cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="], "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], - "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], + "chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="], + + "chromium-pickle-js": ["chromium-pickle-js@0.2.0", "", {}, "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw=="], "ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="], "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], + "clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="], + + "cli-cursor": ["cli-cursor@3.1.0", "", { "dependencies": { "restore-cursor": "^3.1.0" } }, "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="], + + "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], + + "cli-truncate": ["cli-truncate@4.0.0", "", { "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" } }, "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA=="], + "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + "clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="], + + "clone-response": ["clone-response@1.0.3", "", { "dependencies": { "mimic-response": "^1.0.0" } }, "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA=="], + "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], "cmdk": ["cmdk@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "^1.1.1", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-id": "^1.1.0", "@radix-ui/react-primitive": "^2.0.2" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg=="], @@ -1418,6 +1569,8 @@ "common-tags": ["common-tags@1.8.2", "", {}, "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA=="], + "compare-version": ["compare-version@0.1.2", "", {}, "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A=="], + "compressible": ["compressible@2.0.18", "", { "dependencies": { "mime-db": ">= 1.43.0 < 2" } }, "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg=="], "compression": ["compression@1.8.1", "", { "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", "debug": "2.6.9", "negotiator": "~0.6.4", "on-headers": "~1.1.0", "safe-buffer": "5.2.1", "vary": "~1.1.2" } }, "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w=="], @@ -1438,12 +1591,18 @@ "core-js-compat": ["core-js-compat@3.48.0", "", { "dependencies": { "browserslist": "^4.28.1" } }, "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q=="], + "core-util-is": ["core-util-is@1.0.2", "", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="], + "cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="], + "crc": ["crc@3.8.0", "", { "dependencies": { "buffer": "^5.1.0" } }, "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ=="], + "crelt": ["crelt@1.0.6", "", {}, "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="], "cron-parser": ["cron-parser@4.9.0", "", { "dependencies": { "luxon": "^3.2.1" } }, "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q=="], + "cross-dirname": ["cross-dirname@0.1.0", "", {}, "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q=="], + "cross-env": ["cross-env@7.0.3", "", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], @@ -1474,6 +1633,8 @@ "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], + "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="], + "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], @@ -1484,6 +1645,10 @@ "default-browser-id": ["default-browser-id@5.0.1", "", {}, "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q=="], + "defaults": ["defaults@1.0.4", "", { "dependencies": { "clone": "^1.0.2" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="], + + "defer-to-connect": ["defer-to-connect@2.0.1", "", {}, "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="], + "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], "define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="], @@ -1498,6 +1663,8 @@ "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "detect-node": ["detect-node@2.1.0", "", {}, "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="], + "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], @@ -1506,6 +1673,12 @@ "dijkstrajs": ["dijkstrajs@1.0.3", "", {}, "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="], + "dir-compare": ["dir-compare@4.2.0", "", { "dependencies": { "minimatch": "^3.0.5", "p-limit": "^3.1.0 " } }, "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ=="], + + "dmg-builder": ["dmg-builder@26.8.1", "", { "dependencies": { "app-builder-lib": "26.8.1", "builder-util": "26.8.1", "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" }, "optionalDependencies": { "dmg-license": "^1.0.11" } }, "sha512-glMJgnTreo8CFINujtAhCgN96QAqApDMZ8Vl1r8f0QT8QprvC1UCltV4CcWj20YoIyLZx6IUskaJZ0NV8fokcg=="], + + "dmg-license": ["dmg-license@1.0.11", "", { "dependencies": { "@types/plist": "^3.0.1", "@types/verror": "^1.10.3", "ajv": "^6.10.0", "crc": "^3.8.0", "iconv-corefoundation": "^1.1.7", "plist": "^3.0.4", "smart-buffer": "^4.0.2", "verror": "^1.10.0" }, "os": "darwin", "bin": { "dmg-license": "bin/dmg-license.js" } }, "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q=="], + "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], @@ -1516,8 +1689,14 @@ "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], + "dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], + + "dotenv-expand": ["dotenv-expand@11.0.7", "", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="], + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], + "eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="], + "ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="], "editions": ["editions@6.22.0", "", { "dependencies": { "version-range": "^4.15.0" } }, "sha512-UgGlf8IW75je7HZjNDpJdCv4cGJWIi6yumFdZ0R7A8/CIhQiWUjyGLCxdHpd8bmyD1gnkfUNK0oeOXqUS2cpfQ=="], @@ -1526,14 +1705,36 @@ "ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], + "electron": ["electron@41.2.1", "", { "dependencies": { "@electron/get": "^2.0.0", "@types/node": "^24.9.0", "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js" } }, "sha512-teeRThiYGTPKf/2yOW7zZA1bhb91KEQ4yLBPOg7GxpmnkLFLugKgQaAKOrCgdzwsXh/5mFIfmkm+4+wACJKwaA=="], + + "electron-builder": ["electron-builder@26.8.1", "", { "dependencies": { "app-builder-lib": "26.8.1", "builder-util": "26.8.1", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "ci-info": "^4.2.0", "dmg-builder": "26.8.1", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "simple-update-notifier": "2.0.0", "yargs": "^17.6.2" }, "bin": { "electron-builder": "cli.js", "install-app-deps": "install-app-deps.js" } }, "sha512-uWhx1r74NGpCagG0ULs/P9Nqv2nsoo+7eo4fLUOB8L8MdWltq9odW/uuLXMFCDGnPafknYLZgjNX0ZIFRzOQAw=="], + + "electron-builder-squirrel-windows": ["electron-builder-squirrel-windows@26.8.1", "", { "dependencies": { "app-builder-lib": "26.8.1", "builder-util": "26.8.1", "electron-winstaller": "5.4.0" } }, "sha512-o288fIdgPLHA76eDrFADHPoo7VyGkDCYbLV1GzndaMSAVBoZrGvM9m2IehdcVMzdAZJ2eV9bgyissQXHv5tGzA=="], + + "electron-context-menu": ["electron-context-menu@4.1.2", "", { "dependencies": { "cli-truncate": "^4.0.0", "electron-dl": "^4.0.0", "electron-is-dev": "^3.0.1" } }, "sha512-9xYTUV0oRqKL50N9W71IrXNdVRB0LuBp3R1zkUdUc2wfIa2/QZwYYj5RLuO7Tn7ZSLVIaO3X6u+EIBK+cBvzrQ=="], + + "electron-dl": ["electron-dl@4.0.0", "", { "dependencies": { "ext-name": "^5.0.0", "pupa": "^3.1.0", "unused-filename": "^4.0.1" } }, "sha512-USiB9816d2JzKv0LiSbreRfTg5lDk3lWh0vlx/gugCO92ZIJkHVH0UM18EHvKeadErP6Xn4yiTphWzYfbA2Ong=="], + + "electron-is-dev": ["electron-is-dev@3.0.1", "", {}, "sha512-8TjjAh8Ec51hUi3o4TaU0mD3GMTOESi866oRNavj9A3IQJ7pmv+MJVmdZBFGw4GFT36X7bkqnuDNYvkQgvyI8Q=="], + + "electron-log": ["electron-log@5.4.3", "", {}, "sha512-sOUsM3LjZdugatazSQ/XTyNcw8dfvH1SYhXWiJyfYodAAKOZdHs0txPiLDXFzOZbhXgAgshQkshH2ccq0feyLQ=="], + + "electron-publish": ["electron-publish@26.8.1", "", { "dependencies": { "@types/fs-extra": "^9.0.11", "builder-util": "26.8.1", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "form-data": "^4.0.5", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "mime": "^2.5.2" } }, "sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w=="], + "electron-to-chromium": ["electron-to-chromium@1.5.302", "", {}, "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg=="], + "electron-updater": ["electron-updater@6.8.3", "", { "dependencies": { "builder-util-runtime": "9.5.1", "fs-extra": "^10.1.0", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", "lodash.escaperegexp": "^4.1.2", "lodash.isequal": "^4.5.0", "semver": "~7.7.3", "tiny-typed-emitter": "^2.1.0" } }, "sha512-Z6sgw3jgbikWKXei1ENdqFOxBP0WlXg3TtKfz0rgw2vIZFJUyI4pD7ZN7jrkm7EoMK+tcm/qTnPUdqfZukBlBQ=="], + + "electron-winstaller": ["electron-winstaller@5.4.0", "", { "dependencies": { "@electron/asar": "^3.2.1", "debug": "^4.1.1", "fs-extra": "^7.0.1", "lodash": "^4.17.21", "temp": "^0.9.0" }, "optionalDependencies": { "@electron/windows-sign": "^1.1.2" } }, "sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg=="], + "elkjs": ["elkjs@0.11.0", "", {}, "sha512-u4J8h9mwEDaYMqo0RYJpqNMFDoMK7f+pu4GjcV+N8jIC7TRdORgzkfSjTJemhqONFfH6fBI3wpysgWbhgVWIXw=="], "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], + "encoding": ["encoding@0.1.13", "", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="], + "encoding-sniffer": ["encoding-sniffer@0.2.1", "", { "dependencies": { "iconv-lite": "^0.6.3", "whatwg-encoding": "^3.1.1" } }, "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw=="], "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], @@ -1542,24 +1743,34 @@ "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], + "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], + "err-code": ["err-code@2.0.3", "", {}, "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="], + "es-abstract": ["es-abstract@1.24.1", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw=="], "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], + "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], "es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="], + "es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="], + "esbuild": ["esbuild@0.24.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.24.2", "@esbuild/android-arm": "0.24.2", "@esbuild/android-arm64": "0.24.2", "@esbuild/android-x64": "0.24.2", "@esbuild/darwin-arm64": "0.24.2", "@esbuild/darwin-x64": "0.24.2", "@esbuild/freebsd-arm64": "0.24.2", "@esbuild/freebsd-x64": "0.24.2", "@esbuild/linux-arm": "0.24.2", "@esbuild/linux-arm64": "0.24.2", "@esbuild/linux-ia32": "0.24.2", "@esbuild/linux-loong64": "0.24.2", "@esbuild/linux-mips64el": "0.24.2", "@esbuild/linux-ppc64": "0.24.2", "@esbuild/linux-riscv64": "0.24.2", "@esbuild/linux-s390x": "0.24.2", "@esbuild/linux-x64": "0.24.2", "@esbuild/netbsd-arm64": "0.24.2", "@esbuild/netbsd-x64": "0.24.2", "@esbuild/openbsd-arm64": "0.24.2", "@esbuild/openbsd-x64": "0.24.2", "@esbuild/sunos-x64": "0.24.2", "@esbuild/win32-arm64": "0.24.2", "@esbuild/win32-ia32": "0.24.2", "@esbuild/win32-x64": "0.24.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA=="], "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + "escape-goat": ["escape-goat@4.0.0", "", {}, "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg=="], + "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], @@ -1584,7 +1795,7 @@ "estree-util-is-identifier-name": ["estree-util-is-identifier-name@3.0.0", "", {}, "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg=="], - "estree-walker": ["estree-walker@1.0.1", "", {}, "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg=="], + "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], @@ -1596,10 +1807,22 @@ "expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="], + "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], + + "exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], + "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], + "ext-list": ["ext-list@2.2.2", "", { "dependencies": { "mime-db": "^1.28.0" } }, "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA=="], + + "ext-name": ["ext-name@5.0.0", "", { "dependencies": { "ext-list": "^2.0.0", "sort-keys-length": "^1.0.0" } }, "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ=="], + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + "extract-zip": ["extract-zip@2.0.1", "", { "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "optionalDependencies": { "@types/yauzl": "^2.9.1" }, "bin": { "extract-zip": "cli.js" } }, "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="], + + "extsprintf": ["extsprintf@1.4.1", "", {}, "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA=="], + "fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="], "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], @@ -1622,6 +1845,8 @@ "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], + "file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="], + "filelist": ["filelist@1.0.6", "", { "dependencies": { "minimatch": "^5.0.1" } }, "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA=="], "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], @@ -1662,6 +1887,10 @@ "fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="], + "fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="], + + "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], @@ -1678,6 +1907,8 @@ "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + "get-east-asian-width": ["get-east-asian-width@1.5.0", "", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="], + "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], @@ -1686,6 +1917,8 @@ "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + "get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], + "get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="], "get-tsconfig": ["get-tsconfig@4.13.6", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw=="], @@ -1698,6 +1931,8 @@ "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], + "global-agent": ["global-agent@3.0.0", "", { "dependencies": { "boolean": "^3.0.1", "es6-error": "^4.1.1", "matcher": "^3.0.0", "roarr": "^2.15.3", "semver": "^7.3.2", "serialize-error": "^7.0.1" } }, "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q=="], + "globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="], "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], @@ -1706,6 +1941,8 @@ "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], + "got": ["got@11.8.6", "", { "dependencies": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", "@types/cacheable-request": "^6.0.1", "@types/responselike": "^1.0.0", "cacheable-lookup": "^5.0.3", "cacheable-request": "^7.0.2", "decompress-response": "^6.0.0", "http2-wrapper": "^1.0.0-beta.5.2", "lowercase-keys": "^2.0.0", "p-cancelable": "^2.0.0", "responselike": "^2.0.0" } }, "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g=="], + "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], "has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="], @@ -1760,6 +1997,8 @@ "htmlparser2": ["htmlparser2@10.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "entities": "^7.0.1" } }, "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ=="], + "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], + "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], "http-proxy": ["http-proxy@1.18.1", "", { "dependencies": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", "requires-port": "^1.0.0" } }, "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ=="], @@ -1768,12 +2007,16 @@ "http-proxy-middleware": ["http-proxy-middleware@3.0.5", "", { "dependencies": { "@types/http-proxy": "^1.17.15", "debug": "^4.3.6", "http-proxy": "^1.18.1", "is-glob": "^4.0.3", "is-plain-object": "^5.0.0", "micromatch": "^4.0.8" } }, "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg=="], + "http2-wrapper": ["http2-wrapper@1.0.3", "", { "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" } }, "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg=="], + "http_ece": ["http_ece@1.2.0", "", {}, "sha512-JrF8SSLVmcvc5NducxgyOrKXe3EsyHMgBFgSaIUGmArKe+rwr0uphRkRXvwiom3I+fpIfoItveHrfudL8/rxuA=="], "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], "humanize-ms": ["humanize-ms@1.2.1", "", { "dependencies": { "ms": "^2.0.0" } }, "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ=="], + "iconv-corefoundation": ["iconv-corefoundation@1.1.7", "", { "dependencies": { "cli-truncate": "^2.1.0", "node-addon-api": "^1.6.3" }, "os": "darwin" }, "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ=="], + "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], "idb": ["idb@7.1.1", "", {}, "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ=="], @@ -1788,8 +2031,14 @@ "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], + "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], + "index-to-position": ["index-to-position@1.2.0", "", {}, "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw=="], + "infer-owner": ["infer-owner@1.0.4", "", {}, "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="], + + "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], @@ -1800,6 +2049,8 @@ "intl-messageformat": ["intl-messageformat@10.7.18", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.6", "@formatjs/fast-memoize": "2.2.7", "@formatjs/icu-messageformat-parser": "2.11.4", "tslib": "^2.8.0" } }, "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g=="], + "ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="], + "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], "is-alphabetical": ["is-alphabetical@1.0.4", "", {}, "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg=="], @@ -1844,6 +2095,10 @@ "is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="], + "is-interactive": ["is-interactive@1.0.0", "", {}, "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="], + + "is-lambda": ["is-lambda@1.0.1", "", {}, "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ=="], + "is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="], "is-module": ["is-module@1.0.0", "", {}, "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="], @@ -1878,6 +2133,8 @@ "is-typed-array": ["is-typed-array@1.1.15", "", { "dependencies": { "which-typed-array": "^1.1.16" } }, "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ=="], + "is-unicode-supported": ["is-unicode-supported@0.1.0", "", {}, "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="], + "is-weakmap": ["is-weakmap@2.0.2", "", {}, "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w=="], "is-weakref": ["is-weakref@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew=="], @@ -1888,6 +2145,8 @@ "isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], + "isbinaryfile": ["isbinaryfile@5.0.7", "", {}, "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ=="], + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "istextorbinary": ["istextorbinary@9.5.0", "", { "dependencies": { "binaryextensions": "^6.11.0", "editions": "^6.21.0", "textextensions": "^6.11.0" } }, "sha512-5mbUj3SiZXCuRf9fT3ibzbSSEWiy63gFfksmGfdOzujPjW3k+z8WvIBxcJHBoQNlaZaiyB25deviif2+osLmLw=="], @@ -1916,6 +2175,8 @@ "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], + "json-stringify-safe": ["json-stringify-safe@5.0.1", "", {}, "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="], + "json-with-bigint": ["json-with-bigint@3.5.7", "", {}, "sha512-7ei3MdAI5+fJPVnKlW77TKNKwQ5ppSzWvhPuSuINT/GYW9ZOC1eRKOuhV9yHG5aEsUPj9BBx5JIekkmoLHxZOw=="], "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], @@ -1942,6 +2203,8 @@ "klaw-sync": ["klaw-sync@6.0.0", "", { "dependencies": { "graceful-fs": "^4.1.11" } }, "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ=="], + "lazy-val": ["lazy-val@1.0.5", "", {}, "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q=="], + "leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="], "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], @@ -1980,10 +2243,14 @@ "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="], + "lodash.escaperegexp": ["lodash.escaperegexp@4.1.2", "", {}, "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw=="], + "lodash.includes": ["lodash.includes@4.3.0", "", {}, "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="], "lodash.isboolean": ["lodash.isboolean@3.0.3", "", {}, "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="], + "lodash.isequal": ["lodash.isequal@4.5.0", "", {}, "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="], + "lodash.isinteger": ["lodash.isinteger@4.0.4", "", {}, "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="], "lodash.isnumber": ["lodash.isnumber@3.0.3", "", {}, "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="], @@ -2000,8 +2267,14 @@ "lodash.truncate": ["lodash.truncate@4.4.2", "", {}, "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw=="], + "log-symbols": ["log-symbols@4.1.0", "", { "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="], + "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], + "loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="], + + "lowercase-keys": ["lowercase-keys@2.0.0", "", {}, "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="], + "lowlight": ["lowlight@1.20.0", "", { "dependencies": { "fault": "^1.0.0", "highlight.js": "~10.7.0" } }, "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw=="], "lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], @@ -2012,12 +2285,16 @@ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + "make-fetch-happen": ["make-fetch-happen@10.2.1", "", { "dependencies": { "agentkeepalive": "^4.2.1", "cacache": "^16.1.0", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-fetch": "^2.0.3", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", "promise-retry": "^2.0.1", "socks-proxy-agent": "^7.0.0", "ssri": "^9.0.0" } }, "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w=="], + "markdown-it": ["markdown-it@14.1.1", "", { "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", "linkify-it": "^5.0.0", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" }, "bin": { "markdown-it": "bin/markdown-it.mjs" } }, "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA=="], "markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="], "marked": ["marked@17.0.3", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-jt1v2ObpyOKR8p4XaUJVk3YWRJ5n+i4+rjQopxvV32rSndTJXvIzuUdWWIy/1pFQMkQmvTXawzDNqOH/CUmx6A=="], + "matcher": ["matcher@3.0.0", "", { "dependencies": { "escape-string-regexp": "^4.0.0" } }, "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="], + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], "mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="], @@ -2126,6 +2403,8 @@ "mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], "minimalistic-assert": ["minimalistic-assert@1.0.1", "", {}, "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="], @@ -2134,7 +2413,21 @@ "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], - "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + "minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="], + + "minipass-collect": ["minipass-collect@1.0.2", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA=="], + + "minipass-fetch": ["minipass-fetch@2.1.2", "", { "dependencies": { "minipass": "^3.1.6", "minipass-sized": "^1.0.3", "minizlib": "^2.1.2" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA=="], + + "minipass-flush": ["minipass-flush@1.0.7", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA=="], + + "minipass-pipeline": ["minipass-pipeline@1.2.4", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A=="], + + "minipass-sized": ["minipass-sized@1.0.3", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g=="], + + "minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="], + + "mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="], @@ -2164,10 +2457,14 @@ "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], + "node-api-version": ["node-api-version@0.2.1", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q=="], + "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="], "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + "node-gyp": ["node-gyp@11.5.0", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^14.0.3", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "tar": "^7.4.3", "tinyglobby": "^0.2.12", "which": "^5.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ=="], + "node-pty": ["node-pty@1.2.0-beta.12", "", { "dependencies": { "node-addon-api": "^7.1.0" } }, "sha512-uExTCG/4VmSJa4+TjxFwPXv8BfacmfFEBL6JpxCMDghcwqzvD0yTcGmZ1fKOK6HY33tp0CelLblqTECJizc+Yw=="], "node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="], @@ -2176,10 +2473,14 @@ "nodemon": ["nodemon@3.1.14", "", { "dependencies": { "chokidar": "^3.5.2", "debug": "^4", "ignore-by-default": "^1.0.1", "minimatch": "^10.2.1", "pstree.remy": "^1.1.8", "semver": "^7.5.3", "simple-update-notifier": "^2.0.0", "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.5" }, "bin": { "nodemon": "bin/nodemon.js" } }, "sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw=="], + "nopt": ["nopt@6.0.0", "", { "dependencies": { "abbrev": "^1.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g=="], + "normalize-package-data": ["normalize-package-data@6.0.2", "", { "dependencies": { "hosted-git-info": "^7.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" } }, "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g=="], "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], + "normalize-url": ["normalize-url@6.1.0", "", {}, "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="], + "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], @@ -2196,6 +2497,8 @@ "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], + "oniguruma-parser": ["oniguruma-parser@0.12.1", "", {}, "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w=="], "oniguruma-to-es": ["oniguruma-to-es@4.3.4", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA=="], @@ -2208,8 +2511,12 @@ "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], + "ora": ["ora@5.4.1", "", { "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", "cli-cursor": "^3.1.0", "cli-spinners": "^2.5.0", "is-interactive": "^1.0.0", "is-unicode-supported": "^0.1.0", "log-symbols": "^4.1.0", "strip-ansi": "^6.0.0", "wcwidth": "^1.0.1" } }, "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ=="], + "own-keys": ["own-keys@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" } }, "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg=="], + "p-cancelable": ["p-cancelable@2.1.1", "", {}, "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg=="], + "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], @@ -2240,6 +2547,8 @@ "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], + "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], @@ -2250,12 +2559,20 @@ "path-type": ["path-type@6.0.0", "", {}, "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ=="], + "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + + "pathval": ["pathval@2.0.1", "", {}, "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ=="], + + "pe-library": ["pe-library@0.4.1", "", {}, "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw=="], + "pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="], "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + "plist": ["plist@3.1.0", "", { "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ=="], + "pluralize": ["pluralize@8.0.0", "", {}, "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA=="], "pngjs": ["pngjs@5.0.0", "", {}, "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="], @@ -2266,6 +2583,8 @@ "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], + "postject": ["postject@1.0.0-alpha.6", "", { "dependencies": { "commander": "^9.4.0" }, "bin": { "postject": "dist/cli.js" } }, "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A=="], + "prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="], "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], @@ -2274,6 +2593,16 @@ "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="], + "proc-log": ["proc-log@2.0.1", "", {}, "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw=="], + + "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], + + "promise-inflight": ["promise-inflight@1.0.1", "", {}, "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g=="], + + "promise-retry": ["promise-retry@2.0.1", "", { "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="], + + "proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="], + "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], @@ -2286,6 +2615,8 @@ "punycode.js": ["punycode.js@2.3.1", "", {}, "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA=="], + "pupa": ["pupa@3.3.0", "", { "dependencies": { "escape-goat": "^4.0.0" } }, "sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA=="], + "pvtsutils": ["pvtsutils@1.3.6", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg=="], "pvutils": ["pvutils@1.1.5", "", {}, "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA=="], @@ -2298,6 +2629,8 @@ "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + "quick-lru": ["quick-lru@5.1.1", "", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="], + "randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="], "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], @@ -2326,6 +2659,8 @@ "read": ["read@1.0.7", "", { "dependencies": { "mute-stream": "~0.0.4" } }, "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ=="], + "read-binary-file-arch": ["read-binary-file-arch@1.0.6", "", { "dependencies": { "debug": "^4.3.4" }, "bin": { "read-binary-file-arch": "cli.js" } }, "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg=="], + "read-pkg": ["read-pkg@9.0.1", "", { "dependencies": { "@types/normalize-package-data": "^2.4.3", "normalize-package-data": "^6.0.0", "parse-json": "^8.0.0", "type-fest": "^4.6.0", "unicorn-magic": "^0.1.0" } }, "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA=="], "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], @@ -2378,16 +2713,30 @@ "requires-port": ["requires-port@1.0.0", "", {}, "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="], + "resedit": ["resedit@1.7.2", "", { "dependencies": { "pe-library": "^0.4.1" } }, "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA=="], + "reselect": ["reselect@5.1.1", "", {}, "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w=="], "resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], + "resolve-alpn": ["resolve-alpn@1.2.1", "", {}, "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="], + "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], + "responselike": ["responselike@2.0.1", "", { "dependencies": { "lowercase-keys": "^2.0.0" } }, "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw=="], + + "restore-cursor": ["restore-cursor@3.1.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA=="], + + "retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], + "rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="], + + "roarr": ["roarr@2.15.4", "", { "dependencies": { "boolean": "^3.0.1", "detect-node": "^2.0.4", "globalthis": "^1.0.1", "json-stringify-safe": "^5.0.1", "semver-compare": "^1.0.0", "sprintf-js": "^1.1.2" } }, "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A=="], + "rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="], "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], @@ -2408,6 +2757,8 @@ "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + "sanitize-filename": ["sanitize-filename@1.6.4", "", { "dependencies": { "truncate-utf8-bytes": "^1.0.0" } }, "sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg=="], + "sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="], "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], @@ -2416,8 +2767,12 @@ "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + "semver-compare": ["semver-compare@1.0.0", "", {}, "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="], + "send": ["send@1.2.1", "", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="], + "serialize-error": ["serialize-error@7.0.1", "", { "dependencies": { "type-fest": "^0.13.1" } }, "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw=="], + "serialize-javascript": ["serialize-javascript@6.0.2", "", { "dependencies": { "randombytes": "^2.1.0" } }, "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g=="], "serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], @@ -2448,7 +2803,9 @@ "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], - "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], + + "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], "simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="], @@ -2464,12 +2821,22 @@ "slash": ["slash@2.0.0", "", {}, "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A=="], - "slice-ansi": ["slice-ansi@4.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" } }, "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ=="], + "slice-ansi": ["slice-ansi@5.0.0", "", { "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ=="], + + "smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], "smob": ["smob@1.6.1", "", {}, "sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g=="], + "socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], + + "socks-proxy-agent": ["socks-proxy-agent@7.0.0", "", { "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", "socks": "^2.6.2" } }, "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww=="], + "sonner": ["sonner@2.0.7", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w=="], + "sort-keys": ["sort-keys@1.1.2", "", { "dependencies": { "is-plain-obj": "^1.0.0" } }, "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg=="], + + "sort-keys-length": ["sort-keys-length@1.0.1", "", { "dependencies": { "sort-keys": "^1.0.0" } }, "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw=="], + "source-map": ["source-map@0.8.0-beta.0", "", { "dependencies": { "whatwg-url": "^7.0.0" } }, "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA=="], "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], @@ -2488,12 +2855,24 @@ "spdx-license-ids": ["spdx-license-ids@3.0.23", "", {}, "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw=="], + "sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], + + "ssri": ["ssri@9.0.1", "", { "dependencies": { "minipass": "^3.1.1" } }, "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q=="], + + "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], + + "stat-mode": ["stat-mode@1.0.0", "", {}, "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg=="], + "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="], + "stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="], "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "string.prototype.matchall": ["string.prototype.matchall@4.0.12", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA=="], "string.prototype.trim": ["string.prototype.trim@1.2.10", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-data-property": "^1.1.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-object-atoms": "^1.0.0", "has-property-descriptors": "^1.0.2" } }, "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA=="], @@ -2510,10 +2889,14 @@ "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "strip-comments": ["strip-comments@2.0.1", "", {}, "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw=="], "strip-json-comments": ["strip-json-comments@5.0.3", "", {}, "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw=="], + "strip-literal": ["strip-literal@3.1.0", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg=="], + "structured-source": ["structured-source@4.0.0", "", { "dependencies": { "boundary": "^2.0.0" } }, "sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA=="], "style-mod": ["style-mod@4.1.3", "", {}, "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ=="], @@ -2522,6 +2905,8 @@ "style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="], + "sumchecker": ["sumchecker@3.0.1", "", { "dependencies": { "debug": "^4.1.0" } }, "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg=="], + "supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], "supports-hyperlinks": ["supports-hyperlinks@3.2.0", "", { "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" } }, "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig=="], @@ -2538,12 +2923,18 @@ "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], + "tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="], + "tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="], "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], + "temp": ["temp@0.9.4", "", { "dependencies": { "mkdirp": "^0.5.1", "rimraf": "~2.6.2" } }, "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA=="], + "temp-dir": ["temp-dir@2.0.0", "", {}, "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg=="], + "temp-file": ["temp-file@3.4.0", "", { "dependencies": { "async-exit-hook": "^2.0.1", "fs-extra": "^10.0.0" } }, "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg=="], + "tempy": ["tempy@0.6.0", "", { "dependencies": { "is-stream": "^2.0.0", "temp-dir": "^2.0.0", "type-fest": "^0.16.0", "unique-string": "^2.0.0" } }, "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw=="], "terminal-link": ["terminal-link@4.0.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "supports-hyperlinks": "^3.2.0" } }, "sha512-lk+vH+MccxNqgVqSnkMVKx4VLJfnLjDBGzH16JVZjKE2DoxP57s6/vt6JmXV5I3jBcfGrxNrYtC+mPtU7WJztA=="], @@ -2554,10 +2945,26 @@ "textextensions": ["textextensions@6.11.0", "", { "dependencies": { "editions": "^6.21.0" } }, "sha512-tXJwSr9355kFJI3lbCkPpUH5cP8/M0GGy2xLO34aZCjMXBaK3SoPnZwr/oWmo1FdCnELcs4npdCIOFtq9W3ruQ=="], + "tiny-async-pool": ["tiny-async-pool@1.3.0", "", { "dependencies": { "semver": "^5.5.0" } }, "sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA=="], + + "tiny-typed-emitter": ["tiny-typed-emitter@2.1.0", "", {}, "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA=="], + + "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], + + "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], + "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + "tinypool": ["tinypool@1.1.1", "", {}, "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg=="], + + "tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], + + "tinyspy": ["tinyspy@4.0.4", "", {}, "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q=="], + "tmp": ["tmp@0.2.5", "", {}, "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow=="], + "tmp-promise": ["tmp-promise@3.0.3", "", { "dependencies": { "tmp": "^0.2.0" } }, "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ=="], + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], @@ -2572,6 +2979,8 @@ "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], + "truncate-utf8-bytes": ["truncate-utf8-bytes@1.0.2", "", { "dependencies": { "utf8-byte-length": "^1.0.1" } }, "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ=="], + "ts-api-utils": ["ts-api-utils@2.4.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA=="], "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], @@ -2630,6 +3039,10 @@ "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], + "unique-filename": ["unique-filename@2.0.1", "", { "dependencies": { "unique-slug": "^3.0.0" } }, "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A=="], + + "unique-slug": ["unique-slug@3.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w=="], + "unique-string": ["unique-string@2.0.0", "", { "dependencies": { "crypto-random-string": "^2.0.0" } }, "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg=="], "unist-util-find-after": ["unist-util-find-after@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ=="], @@ -2652,6 +3065,8 @@ "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], + "unused-filename": ["unused-filename@4.0.1", "", { "dependencies": { "escape-string-regexp": "^5.0.0", "path-exists": "^5.0.0" } }, "sha512-ZX6U1J04K1FoSUeoX1OicAhw4d0aro2qo+L8RhJkiGTNtBNkd/Fi1Wxoc9HzcVu6HfOzm0si/N15JjxFmD1z6A=="], + "upath": ["upath@1.2.0", "", {}, "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="], "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], @@ -2666,6 +3081,8 @@ "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], + "utf8-byte-length": ["utf8-byte-length@1.0.5", "", {}, "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA=="], + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], "uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], @@ -2674,6 +3091,8 @@ "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], + "verror": ["verror@1.10.1", "", { "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg=="], + "version-range": ["version-range@4.15.0", "", {}, "sha512-Ck0EJbAGxHwprkzFO966t4/5QkRuzh+/I1RxhLgUKKwEn+Cd8NwM60mE3AqBZg5gYODoXW0EFsQvbZjRlvdqbg=="], "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], @@ -2684,10 +3103,16 @@ "vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="], + "vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="], + "vite-plugin-pwa": ["vite-plugin-pwa@1.2.0", "", { "dependencies": { "debug": "^4.3.6", "pretty-bytes": "^6.1.1", "tinyglobby": "^0.2.10", "workbox-build": "^7.4.0", "workbox-window": "^7.4.0" }, "peerDependencies": { "@vite-pwa/assets-generator": "^1.0.0", "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@vite-pwa/assets-generator"] }, "sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw=="], + "vitest": ["vitest@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", "@vitest/mocker": "3.2.4", "@vitest/pretty-format": "^3.2.4", "@vitest/runner": "3.2.4", "@vitest/snapshot": "3.2.4", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.4", "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A=="], + "w3c-keyname": ["w3c-keyname@2.2.8", "", {}, "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="], + "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], + "web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="], "web-push": ["web-push@3.6.7", "", { "dependencies": { "asn1.js": "^5.3.0", "http_ece": "1.2.0", "https-proxy-agent": "^7.0.0", "jws": "^4.0.0", "minimist": "^1.2.5" }, "bin": { "web-push": "src/cli.js" } }, "sha512-OpiIUe8cuGjrj3mMBFWY+e4MMIkW3SVT+7vEIjvD9kejGUypv8GPDf84JdPWskK8zMRIJ6xYGm+Kxr8YkPyA0A=="], @@ -2714,6 +3139,8 @@ "which-typed-array": ["which-typed-array@1.1.20", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg=="], + "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], + "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], "workbox-background-sync": ["workbox-background-sync@7.4.0", "", { "dependencies": { "idb": "^7.0.1", "workbox-core": "7.4.0" } }, "sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w=="], @@ -2750,6 +3177,8 @@ "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + "wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], "ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], @@ -2800,6 +3229,28 @@ "@babel/preset-env/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "@electron/asar/commander": ["commander@5.1.0", "", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="], + + "@electron/asar/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], + + "@electron/fuses/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + + "@electron/get/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], + + "@electron/get/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@electron/node-gyp/glob": ["glob@8.1.0", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" } }, "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ=="], + + "@electron/notarize/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + + "@electron/osx-sign/isbinaryfile": ["isbinaryfile@4.0.10", "", {}, "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw=="], + + "@electron/universal/fs-extra": ["fs-extra@11.3.3", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="], + + "@electron/universal/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], + + "@electron/windows-sign/fs-extra": ["fs-extra@11.3.3", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="], + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], @@ -2808,6 +3259,14 @@ "@heroui/theme/tailwind-merge": ["tailwind-merge@3.4.0", "", {}, "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g=="], + "@isaacs/fs-minipass/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "@malept/flatpak-bundler/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + + "@npmcli/agent/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "@npmcli/agent/socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], + "@openchamber/ui/ghostty-web": ["ghostty-web@0.4.0", "", {}, "sha512-0puDBik2qapbD/QQBW9o5ZHfXnZBqZWx/ctBiVtKZ6ZLds4NYb+wZuw1cRLXZk9zYovIQ908z3rvFhexAvc5Hg=="], "@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], @@ -2834,6 +3293,8 @@ "@rollup/pluginutils/@types/estree": ["@types/estree@0.0.39", "", {}, "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw=="], + "@rollup/pluginutils/estree-walker": ["estree-walker@1.0.1", "", {}, "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg=="], + "@rollup/pluginutils/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "@rollup/pluginutils/rollup": ["rollup@2.80.0", "", { "optionalDependencies": { "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ=="], @@ -2860,6 +3321,8 @@ "@textlint/linter-formatter/pluralize": ["pluralize@2.0.0", "", {}, "sha512-TqNZzQCD4S42De9IfnnBvILN7HAW7riLqsCyp8lgjXeysyPlX5HhqKAcJHHHb9XskE4/a+7VGC9zzx8Ls0jOAw=="], + "@types/plist/xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], + "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], "@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], @@ -2872,30 +3335,70 @@ "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "app-builder-lib/@electron/get": ["@electron/get@3.1.0", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ=="], + + "app-builder-lib/@electron/rebuild": ["@electron/rebuild@4.0.3", "", { "dependencies": { "@malept/cross-spawn-promise": "^2.0.0", "debug": "^4.1.1", "detect-libc": "^2.0.1", "got": "^11.7.0", "graceful-fs": "^4.2.11", "node-abi": "^4.2.0", "node-api-version": "^0.2.1", "node-gyp": "^11.2.0", "ora": "^5.1.0", "read-binary-file-arch": "^1.0.6", "semver": "^7.3.5", "tar": "^7.5.6", "yargs": "^17.0.1" }, "bin": { "electron-rebuild": "lib/cli.js" } }, "sha512-u9vpTHRMkOYCs/1FLiSVAFZ7FbjsXK+bQuzviJZa+lG7BHZl1nz52/IcGvwa3sk80/fc3llutBkbCq10Vh8WQA=="], + + "app-builder-lib/ci-info": ["ci-info@4.3.1", "", {}, "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA=="], + + "app-builder-lib/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + + "app-builder-lib/tar": ["tar@7.5.13", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng=="], + + "app-builder-lib/which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], + "babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "cacache/glob": ["glob@8.1.0", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" } }, "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ=="], + + "cacache/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], + + "cacache/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "cacache/p-map": ["p-map@4.0.0", "", { "dependencies": { "aggregate-error": "^3.0.0" } }, "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ=="], + "chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + "cli-truncate/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "clone-response/mimic-response": ["mimic-response@1.0.1", "", {}, "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="], + "cmdk/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="], "compression/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], "decode-named-character-reference/character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], + "dmg-builder/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "electron-builder/ci-info": ["ci-info@4.4.0", "", {}, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="], + + "electron-publish/mime": ["mime@2.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="], + + "electron-winstaller/fs-extra": ["fs-extra@7.0.1", "", { "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw=="], + + "encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "encoding-sniffer/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "filelist/minimatch": ["minimatch@5.1.9", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw=="], + "foreground-child/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + "form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + "fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + "glob/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + "globby/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], "globby/slash": ["slash@5.1.0", "", {}, "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg=="], @@ -2912,10 +3415,22 @@ "hastscript/space-separated-tokens": ["space-separated-tokens@1.1.5", "", {}, "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA=="], + "iconv-corefoundation/cli-truncate": ["cli-truncate@2.1.0", "", { "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" } }, "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg=="], + + "iconv-corefoundation/node-addon-api": ["node-addon-api@1.7.2", "", {}, "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg=="], + "is-inside-container/is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], "keytar/node-addon-api": ["node-addon-api@4.3.0", "", {}, "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="], + "make-fetch-happen/http-proxy-agent": ["http-proxy-agent@5.0.0", "", { "dependencies": { "@tootallnate/once": "2", "agent-base": "6", "debug": "4" } }, "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w=="], + + "make-fetch-happen/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="], + + "make-fetch-happen/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], + + "make-fetch-happen/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "markdown-it/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], @@ -2924,6 +3439,28 @@ "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "minipass-collect/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minipass-fetch/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minipass-sized/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "node-gyp/make-fetch-happen": ["make-fetch-happen@14.0.3", "", { "dependencies": { "@npmcli/agent": "^3.0.0", "cacache": "^19.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "ssri": "^12.0.0" } }, "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ=="], + + "node-gyp/nopt": ["nopt@8.1.0", "", { "dependencies": { "abbrev": "^3.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A=="], + + "node-gyp/proc-log": ["proc-log@5.0.0", "", {}, "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ=="], + + "node-gyp/tar": ["tar@7.5.13", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng=="], + + "node-gyp/which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], + "node-sarif-builder/fs-extra": ["fs-extra@11.3.3", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="], "nodemon/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], @@ -2942,6 +3479,12 @@ "path-scurry/lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="], + "path-scurry/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "plist/xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], + + "postject/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="], + "qrcode/yargs": ["yargs@15.4.1", "", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="], "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], @@ -2956,22 +3499,52 @@ "refractor/prismjs": ["prismjs@1.27.0", "", {}, "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA=="], + "rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], + + "serialize-error/type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="], + + "slice-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@4.0.0", "", {}, "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ=="], + + "socks-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], + + "sort-keys/is-plain-obj": ["is-plain-obj@1.1.0", "", {}, "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg=="], + "source-map/whatwg-url": ["whatwg-url@7.1.0", "", { "dependencies": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", "webidl-conversions": "^4.0.2" } }, "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg=="], "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + "ssri/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "stringify-entities/character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], + "strip-literal/js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="], + "supports-hyperlinks/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], "table/ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], + "table/slice-ansi": ["slice-ansi@4.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" } }, "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ=="], + + "tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], + + "temp/mkdirp": ["mkdirp@0.5.6", "", { "dependencies": { "minimist": "^1.2.6" }, "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="], + + "temp/rimraf": ["rimraf@2.6.3", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "./bin.js" } }, "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA=="], + "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], + "tiny-async-pool/semver": ["semver@5.7.2", "", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="], + "tsx/esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], "tsyringe/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], + "unused-filename/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + + "unused-filename/path-exists": ["path-exists@5.0.0", "", {}, "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ=="], + "vite/esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], "whatwg-encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], @@ -2992,6 +3565,14 @@ "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + "@electron/get/fs-extra/jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], + + "@electron/get/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + + "@electron/node-gyp/glob/minimatch": ["minimatch@5.1.9", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw=="], + + "@electron/universal/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + "@rollup/plugin-node-resolve/@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "@secretlint/config-loader/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], @@ -3000,8 +3581,36 @@ "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="], + "app-builder-lib/@electron/get/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], + + "app-builder-lib/@electron/get/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "app-builder-lib/@electron/rebuild/node-abi": ["node-abi@4.28.0", "", { "dependencies": { "semver": "^7.6.3" } }, "sha512-Qfp5XZL1cJDOabOT8H5gnqMTmM4NjvYzHp4I/Kt/Sl76OVkOBBHRFlPspGV0hYvMoqQsypFjT/Yp7Km0beXW9g=="], + + "app-builder-lib/minimatch/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="], + + "app-builder-lib/tar/chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], + + "app-builder-lib/tar/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "app-builder-lib/tar/minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], + + "app-builder-lib/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + + "app-builder-lib/which/isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="], + + "cacache/glob/minimatch": ["minimatch@5.1.9", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw=="], + + "cli-truncate/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + + "cli-truncate/string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + "compression/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + "electron-winstaller/fs-extra/jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], + + "electron-winstaller/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + "filelist/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], "form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], @@ -3014,6 +3623,12 @@ "hastscript/@types/hast/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], + "iconv-corefoundation/cli-truncate/slice-ansi": ["slice-ansi@3.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" } }, "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ=="], + + "make-fetch-happen/http-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], + + "make-fetch-happen/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], + "mdast-util-mdx-jsx/parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], "mdast-util-mdx-jsx/parse-entities/character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], @@ -3026,6 +3641,28 @@ "mdast-util-mdx-jsx/parse-entities/is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], + "node-gyp/make-fetch-happen/cacache": ["cacache@19.0.1", "", { "dependencies": { "@npmcli/fs": "^4.0.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^12.0.0", "tar": "^7.4.3", "unique-filename": "^4.0.0" } }, "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ=="], + + "node-gyp/make-fetch-happen/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "node-gyp/make-fetch-happen/minipass-fetch": ["minipass-fetch@4.0.1", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", "minizlib": "^3.0.1" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ=="], + + "node-gyp/make-fetch-happen/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "node-gyp/make-fetch-happen/ssri": ["ssri@12.0.0", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ=="], + + "node-gyp/nopt/abbrev": ["abbrev@3.0.1", "", {}, "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg=="], + + "node-gyp/tar/chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], + + "node-gyp/tar/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "node-gyp/tar/minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], + + "node-gyp/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + + "node-gyp/which/isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="], + "nodemon/minimatch/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="], "nodemon/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], @@ -3048,6 +3685,8 @@ "table/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "temp/rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], + "tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], "tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="], @@ -3150,20 +3789,70 @@ "workbox-build/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "@electron/node-gyp/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + "app-builder-lib/@electron/get/fs-extra/jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], + + "app-builder-lib/@electron/get/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + + "app-builder-lib/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "cacache/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "cli-truncate/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + "glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "mdast-util-mdx-jsx/parse-entities/is-alphanumerical/is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], + "node-gyp/make-fetch-happen/cacache/@npmcli/fs": ["@npmcli/fs@4.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q=="], + + "node-gyp/make-fetch-happen/cacache/fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="], + + "node-gyp/make-fetch-happen/cacache/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], + + "node-gyp/make-fetch-happen/cacache/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "node-gyp/make-fetch-happen/cacache/minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="], + + "node-gyp/make-fetch-happen/cacache/unique-filename": ["unique-filename@4.0.0", "", { "dependencies": { "unique-slug": "^5.0.0" } }, "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ=="], + + "node-gyp/make-fetch-happen/minipass-fetch/minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], + "nodemon/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "qrcode/yargs/cliui/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], "qrcode/yargs/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + "node-gyp/make-fetch-happen/cacache/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], + + "node-gyp/make-fetch-happen/cacache/glob/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], + + "node-gyp/make-fetch-happen/cacache/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], + + "node-gyp/make-fetch-happen/cacache/unique-filename/unique-slug": ["unique-slug@5.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg=="], + "qrcode/yargs/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + "node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], + + "node-gyp/make-fetch-happen/cacache/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + "qrcode/yargs/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], + + "node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], + + "node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], + + "node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], + + "node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], } } diff --git a/docs/TAURI_TO_ELECTRON_CUTOVER.md b/docs/TAURI_TO_ELECTRON_CUTOVER.md new file mode 100644 index 00000000..28a21b53 --- /dev/null +++ b/docs/TAURI_TO_ELECTRON_CUTOVER.md @@ -0,0 +1,349 @@ +# Tauri → Electron auto-update cutover + +> Self-contained playbook. The branch and conversation where this plan was +> designed will not be around when the cutover happens — read this file top to +> bottom and execute; do not assume prior context. + +## What this is + +OpenChamber historically shipped as a Tauri app. A parallel Electron shell was +added on branch `electron-app` (merged to `main` as part of a larger migration). +Since then, both desktop shells have been released in the same GitHub release +and each has its own auto-update channel: + +| Shell | Manifest | Update format | Secret used to sign | +|----------|-------------------|---------------------|---------------------| +| Tauri | `latest.json` | `.tar.gz` + `.sig` | `TAURI_SIGNING_PRIVATE_KEY` (minisign) | +| Electron | `latest-mac.yml` | `.zip` + `blockmap` | Developer ID codesign (APPLE_* secrets) | + +Existing Tauri installs keep their own auto-update path (`latest.json`). +Electron installs auto-update through `latest-mac.yml`. They coexist without +conflict because filenames and manifests differ. + +At some point the user wants to **stop maintaining the Tauri build** and make +the Tauri installs migrate themselves into Electron via auto-update. This +document describes how to do that in a single "transition release". + +## The core trick + +Tauri's updater downloads whatever `.tar.gz` the `latest.json` points at, +verifies the minisign signature, unpacks the contents **over** the existing +`.app` directory, and restarts. It does **not** introspect the payload — it +just replaces files. + +So: produce a `.tar.gz` of the Electron `.app`, sign it with the existing +Tauri minisign key, point `latest.json` at it. Tauri users receive the update, +their `OpenChamber.app` becomes the Electron bundle in-place, and next launch +starts Electron. Subsequent updates go through `latest-mac.yml` +(electron-updater). One-way migration, one-shot workflow change. + +## Prerequisites before running the cutover + +Check all of these before making any release: + +1. **Electron has shipped stable through its own `latest-mac.yml` path for at + least 2 releases.** Verify: + ``` + gh release list --repo btriapitsyn/openchamber + gh release view vX.Y.Z --repo btriapitsyn/openchamber \ + | grep -E 'OpenChamber-.*\.zip|latest-mac\.yml' + ``` + A user on Electron should have successfully auto-updated at least once. + If not, pause and stabilise that path first — don't stack risk. + +2. **`~/.config/openchamber/settings.json` is still the shared state path.** + Tauri `src-tauri/src/main.rs:settings_file_path` and Electron + `packages/electron/main.mjs:settingsFilePath` must both resolve to + `$HOME/.config/openchamber/settings.json`. If either has moved, data parity + breaks and this migration loses user data. Audit both paths, update the + non-migrated shell to match before proceeding. + +3. **Electron `appId` is `dev.openchamber.desktop`** (check + `packages/electron/package.json` `build.appId`). Tauri identifier is + `ai.opencode.openchamber`. These differ intentionally — it means macOS + LaunchServices will re-register after the in-place replace. That's fine but + see "Risks" below. + +4. **All GitHub secrets still valid:** `APPLE_CERTIFICATE`, + `APPLE_CERTIFICATE_PASSWORD`, `APPLE_ID`, `APPLE_PASSWORD`, `APPLE_TEAM_ID`, + `TAURI_SIGNING_PRIVATE_KEY`, `TAURI_SIGNING_PRIVATE_KEY_PASSWORD`. A + workflow_dispatch dry-run should succeed before the real tag. + +5. **`minisign` CLI is available on the macOS runner** (or installable via + brew). Used to sign the Electron tarball with the Tauri key. + +## Release workflow changes + +The file to edit: `.github/workflows/release.yml`. + +Today it has these jobs (simplified): + +``` +create-release +├── build-desktop-macos (Tauri .dmg/.tar.gz/.tar.gz.sig) +├── build-desktop-electron-macos (Electron .dmg/.zip/blockmap/latest-mac.yml) +├── publish-npm +├── combine-manifests (merges Tauri per-arch JSONs → latest.json) +├── combine-electron-manifests (merges Electron per-arch YMLs → latest-mac.yml) +└── finalize-release +``` + +### Step 1 — Remove the Tauri build + +Delete these jobs entirely: +- `build-desktop-macos` +- `combine-manifests` + +They are replaced by the repackage job (below). `finalize-release` `needs:` +list must be updated to drop both. + +### Step 2 — Add a repackage job + +Insert after `build-desktop-electron-macos`: + +```yaml +repackage-electron-as-tauri-update: + needs: [create-release, build-desktop-electron-macos] + runs-on: macos-26 + strategy: + fail-fast: false + matrix: + include: + - arch: arm64 + platform: darwin-aarch64 + - arch: x64 + platform: darwin-x86_64 + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + - uses: actions/setup-node@v4 + with: + node-version: '20' + + # Pull the signed+notarized Electron .app that build-desktop-electron-macos + # already produced. Either re-download the dmg and mount+copy the .app, or + # (cleaner) modify build-desktop-electron-macos to upload the .app itself + # as an artifact so this job can download it. Prefer the latter — adds one + # `actions/upload-artifact@v4` step uploading `packages/electron/dist/mac-/OpenChamber.app`. + + - name: Download signed Electron .app + uses: actions/download-artifact@v4 + with: + name: electron-app-${{ matrix.arch }} + path: staged + + - name: Install minisign + run: brew install minisign + + - name: Tar and sign Electron .app as Tauri update payload + env: + TAURI_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + VERSION: ${{ needs.create-release.outputs.version }} + run: | + set -euo pipefail + cd staged + # The tarball name convention Tauri's updater expects. Must end in + # `.app.tar.gz`. Name stays stable — Tauri updater does not care about + # the inner .app name. + TARBALL="OpenChamber.app.tar.gz" + tar -czf "$TARBALL" OpenChamber.app + + # minisign needs the private key written to a file and a non-interactive + # password via -W (or env). The key in the secret is a minisign secret + # key block (base64-ish multi-line blob). Write to a file verbatim. + echo "$TAURI_KEY" > ../tauri-signing.key + echo "$TAURI_KEY_PASSWORD" | minisign -S -s ../tauri-signing.key \ + -m "$TARBALL" -W + + # Rename per platform so the release has distinct names for arm64/x64. + mv "$TARBALL" "OpenChamber-${VERSION}-${{ matrix.platform }}.app.tar.gz" + mv "${TARBALL}.minisig" "OpenChamber-${VERSION}-${{ matrix.platform }}.app.tar.gz.sig" + + - name: Generate Tauri latest-.json + env: + VERSION: ${{ needs.create-release.outputs.version }} + REPO: ${{ github.repository }} + run: | + SIG=$(cat staged/OpenChamber-${VERSION}-${{ matrix.platform }}.app.tar.gz.sig) + TAR=OpenChamber-${VERSION}-${{ matrix.platform }}.app.tar.gz + cat > staged/latest-${{ matrix.platform }}.json <'); + +try { + process.chdir(os.homedir()); +} catch { +} + +log.initialize(); +log.transports.file.maxSize = 5 * 1024 * 1024; +log.transports.file.level = 'info'; +log.transports.console.level = isDev ? 'debug' : 'warn'; + +const LOG_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000; +try { + const logPath = log.transports.file.getFile().path; + const logDir = path.dirname(logPath); + const cutoff = Date.now() - LOG_MAX_AGE_MS; + for (const entry of fs.readdirSync(logDir)) { + const candidate = path.join(logDir, entry); + try { + const info = fs.statSync(candidate); + if (info.isFile() && info.mtimeMs < cutoff) { + fs.unlinkSync(candidate); + } + } catch { + } + } +} catch { +} + +try { + if (!app.isDefaultProtocolClient(DEEP_LINK_PROTOCOL)) { + app.setAsDefaultProtocolClient(DEEP_LINK_PROTOCOL); + } +} catch (error) { + // log.* not yet initialized at this point; fall back to console. + console.warn('[electron] failed to register deep-link protocol:', error); +} + +const readAppMetadata = () => { + const candidates = [ + path.join(__dirname, 'package.json'), + path.join(__dirname, '..', 'package.json'), + path.join(app.getAppPath?.() || '', 'package.json'), + ].filter(Boolean); + for (const candidate of candidates) { + try { + const raw = fs.readFileSync(candidate, 'utf8'); + const parsed = JSON.parse(raw); + if (parsed?.name === '@openchamber/electron' && typeof parsed.version === 'string') { + return { name: parsed.name, version: parsed.version }; + } + } catch { + } + } + return { name: '@openchamber/electron', version: app.getVersion() }; +}; + +const APP_METADATA = readAppMetadata(); +const APP_VERSION = APP_METADATA.version; + +const DEFAULT_DESKTOP_PORT = 57123; +const MIN_WINDOW_WIDTH = 800; +const MIN_WINDOW_HEIGHT = 520; +const MIN_RESTORE_WINDOW_WIDTH = 900; +const MIN_RESTORE_WINDOW_HEIGHT = 560; +const LOCAL_HOST_ID = 'local'; +const ENV_OVERRIDE_HOST_ID = '__env'; +const CHANGELOG_URL = 'https://raw.githubusercontent.com/btriapitsyn/openchamber/main/CHANGELOG.md'; +const UPDATE_METADATA_URL = 'https://github.com/btriapitsyn/openchamber/releases/latest/download/latest.json'; +const GITHUB_BUG_REPORT_URL = 'https://github.com/btriapitsyn/openchamber/issues/new?template=bug_report.yml'; +const GITHUB_FEATURE_REQUEST_URL = 'https://github.com/btriapitsyn/openchamber/issues/new?template=feature_request.yml'; +const DISCORD_INVITE_URL = 'https://discord.gg/ZYRSdnwwKA'; +const INSTALLED_APPS_CACHE_TTL_SECS = 60 * 60 * 24; +const INSTALLED_APPS_CACHE_FILE = 'discovered-apps.json'; + +const { autoUpdater } = updaterPkg; + +const state = { + serverHandle: null, + sidecarUrl: null, + localOrigin: null, + bootOutcome: null, + initScript: null, + mainWindow: null, + quitRequested: false, + quitConfirmed: false, + quitConfirmationPending: false, + quitRiskPollerStarted: false, + pendingUpdate: null, + unreachableHosts: new Set(), + windowCounter: 1, + focusedWindowIds: new Set(), + windowGeometryRevisions: new Map(), + sshStatuses: new Map(), + sshLogs: new Map(), +}; + +const QUIT_RISK_POLL_INTERVAL_MS = 5_000; +const quitRisk = { + hasActiveTunnel: false, + hasRunningScheduledTasks: false, + hasEnabledScheduledTasks: false, + runningScheduledTasksCount: 0, + enabledScheduledTasksCount: 0, +}; + +const shouldRequireQuitConfirmation = () => + quitRisk.hasActiveTunnel + || quitRisk.hasRunningScheduledTasks + || quitRisk.hasEnabledScheduledTasks; + +const quitConfirmationMessage = () => { + const reasons = []; + if (quitRisk.hasActiveTunnel) { + reasons.push('an active tunnel'); + } + if (quitRisk.runningScheduledTasksCount > 0) { + reasons.push(`${quitRisk.runningScheduledTasksCount} running scheduled task${quitRisk.runningScheduledTasksCount === 1 ? '' : 's'}`); + } + if (quitRisk.enabledScheduledTasksCount > 0) { + reasons.push(`${quitRisk.enabledScheduledTasksCount} enabled scheduled task${quitRisk.enabledScheduledTasksCount === 1 ? '' : 's'}`); + } + if (reasons.length === 0) { + return 'Background processes (sidecar, SSH sessions) will be stopped.'; + } + return `OpenChamber detected ${reasons.join(', ')}. Quitting now will stop sidecar/background processes and may interrupt pending work.`; +}; + +const performConfirmedQuit = () => { + if (state.quitConfirmed) return; + state.quitConfirmed = true; + state.quitRequested = true; + + if (state.mainWindow && !state.mainWindow.isDestroyed()) { + try { + debounceWindowStatePersist(state.mainWindow, true); + } catch { + } + } + + try { + killSidecar(); + } catch { + } + void sshManager.shutdownAll().catch(() => {}); + + // Safety net: force-exit if normal quit sequence stalls (e.g. background + // handles in electron-updater / fetch refs) after a short grace period. + const safety = setTimeout(() => { + app.exit(0); + }, 1500); + if (typeof safety?.unref === 'function') safety.unref(); + + app.quit(); +}; + +const requestQuitWithConfirmation = async () => { + if (!shouldRequireQuitConfirmation()) { + performConfirmedQuit(); + return; + } + + if (state.quitConfirmationPending) { + return; + } + state.quitConfirmationPending = true; + + const windows = BrowserWindow.getAllWindows().filter((window) => !window.isDestroyed()); + const visible = windows.find((window) => window.isVisible()); + if (!visible) { + const hidden = windows.find((window) => !window.isVisible()); + if (hidden) { + hidden.show(); + hidden.focus(); + } + } + + try { + const result = await dialog.showMessageBox({ + type: 'warning', + title: 'Quit OpenChamber?', + message: 'Quit OpenChamber?', + detail: quitConfirmationMessage(), + buttons: ['Quit', 'Cancel'], + defaultId: 1, + cancelId: 1, + }); + state.quitConfirmationPending = false; + if (result.response === 0) { + performConfirmedQuit(); + } + } catch (error) { + state.quitConfirmationPending = false; + log.warn('[electron] quit confirmation dialog failed:', error); + } +}; + +const refreshQuitRiskFlags = async () => { + const base = typeof state.sidecarUrl === 'string' ? state.sidecarUrl.trim().replace(/\/$/, '') : ''; + if (!base) return; + + const scheduledUrl = `${base}/api/openchamber/scheduled-tasks/status`; + const tunnelUrl = `${base}/api/openchamber/tunnel/status`; + + const fetchJson = async (url) => { + try { + const response = await fetch(url, { signal: AbortSignal.timeout(2_000) }); + if (!response.ok) return null; + return await response.json(); + } catch { + return null; + } + }; + + const [scheduled, tunnel] = await Promise.all([fetchJson(scheduledUrl), fetchJson(tunnelUrl)]); + + if (scheduled && typeof scheduled === 'object') { + const enabledCount = Number(scheduled.enabledScheduledTasksCount ?? 0); + const runningCount = Number(scheduled.runningScheduledTasksCount ?? 0); + quitRisk.enabledScheduledTasksCount = Number.isFinite(enabledCount) ? enabledCount : 0; + quitRisk.runningScheduledTasksCount = Number.isFinite(runningCount) ? runningCount : 0; + quitRisk.hasEnabledScheduledTasks = Boolean(scheduled.hasEnabledScheduledTasks) || quitRisk.enabledScheduledTasksCount > 0; + quitRisk.hasRunningScheduledTasks = Boolean(scheduled.hasRunningScheduledTasks) || quitRisk.runningScheduledTasksCount > 0; + } + + if (tunnel && typeof tunnel === 'object') { + quitRisk.hasActiveTunnel = Boolean(tunnel.active); + } +}; + +const startQuitRiskPoller = () => { + if (process.platform !== 'darwin') return; + if (state.quitRiskPollerStarted) return; + state.quitRiskPollerStarted = true; + + const loop = async () => { + while (!state.quitConfirmed && !state.quitRequested) { + await refreshQuitRiskFlags(); + if (state.quitConfirmed || state.quitRequested) break; + await new Promise((resolve) => { + const timer = setTimeout(resolve, QUIT_RISK_POLL_INTERVAL_MS); + if (typeof timer?.unref === 'function') timer.unref(); + }); + } + }; + void loop(); +}; + +const settingsFilePath = () => { + if (typeof process.env.OPENCHAMBER_DATA_DIR === 'string' && process.env.OPENCHAMBER_DATA_DIR.trim()) { + return path.join(process.env.OPENCHAMBER_DATA_DIR.trim(), 'settings.json'); + } + return path.join(os.homedir(), '.config', 'openchamber', 'settings.json'); +}; + +const sshManager = new ElectronSshManager({ + settingsFilePath: settingsFilePath(), + appVersion: APP_VERSION, + emit: (event, detail) => emitToAllWindows(event, detail), +}); + +const readJsonFile = (filePath) => { + try { + return JSON.parse(fs.readFileSync(filePath, 'utf8')); + } catch { + return {}; + } +}; + +const writeJsonFile = async (filePath, data) => { + await fsp.mkdir(path.dirname(filePath), { recursive: true }); + await fsp.writeFile(filePath, JSON.stringify(data, null, 2)); +}; + +const readSettingsRoot = () => { + const root = readJsonFile(settingsFilePath()); + return root && typeof root === 'object' && !Array.isArray(root) ? root : {}; +}; + +const writeSettingsRoot = async (root) => writeJsonFile(settingsFilePath(), root); + +const normalizeHostUrl = (raw) => { + const trimmed = typeof raw === 'string' ? raw.trim() : ''; + if (!trimmed) return null; + try { + const parsed = new URL(trimmed); + if (!['http:', 'https:'].includes(parsed.protocol)) return null; + parsed.hash = ''; + return parsed.toString(); + } catch { + return null; + } +}; + +const sanitizeHostUrlForStorage = (raw) => normalizeHostUrl(raw); + +const readDesktopHostsConfig = () => { + const root = readSettingsRoot(); + const hostsRaw = Array.isArray(root.desktopHosts) ? root.desktopHosts : []; + const hosts = hostsRaw + .map((entry) => { + const id = typeof entry?.id === 'string' ? entry.id.trim() : ''; + const url = sanitizeHostUrlForStorage(entry?.url); + if (!id || id === LOCAL_HOST_ID || !url) return null; + const label = typeof entry?.label === 'string' && entry.label.trim() ? entry.label.trim() : url; + return { id, label, url }; + }) + .filter(Boolean); + + return { + hosts, + defaultHostId: typeof root.desktopDefaultHostId === 'string' && root.desktopDefaultHostId.trim() + ? root.desktopDefaultHostId.trim() + : null, + initialHostChoiceCompleted: root.desktopInitialHostChoiceCompleted === true, + }; +}; + +const writeDesktopHostsConfig = async (config) => { + const root = readSettingsRoot(); + root.desktopHosts = Array.isArray(config?.hosts) + ? config.hosts + .map((entry) => { + const id = typeof entry?.id === 'string' ? entry.id.trim() : ''; + const url = sanitizeHostUrlForStorage(entry?.url); + if (!id || id === LOCAL_HOST_ID || !url) return null; + return { + id, + label: typeof entry?.label === 'string' && entry.label.trim() ? entry.label.trim() : url, + url, + }; + }) + .filter(Boolean) + : []; + root.desktopDefaultHostId = typeof config?.defaultHostId === 'string' && config.defaultHostId.trim() + ? config.defaultHostId.trim() + : null; + if (typeof config?.initialHostChoiceCompleted === 'boolean') { + root.desktopInitialHostChoiceCompleted = config.initialHostChoiceCompleted; + } + await writeSettingsRoot(root); +}; + +const readWindowState = () => { + const stateValue = readSettingsRoot().desktopWindowState; + return stateValue && typeof stateValue === 'object' ? stateValue : null; +}; + +const writeWindowState = async (browserWindow) => { + if (!browserWindow || browserWindow.isDestroyed()) return; + if (!state.mainWindow || browserWindow.id !== state.mainWindow.id) return; + + const bounds = browserWindow.getBounds(); + const root = readSettingsRoot(); + root.desktopWindowState = { + x: bounds.x, + y: bounds.y, + width: Math.max(bounds.width, MIN_WINDOW_WIDTH), + height: Math.max(bounds.height, MIN_WINDOW_HEIGHT), + maximized: browserWindow.isMaximized(), + fullscreen: browserWindow.isFullScreen(), + }; + await writeSettingsRoot(root); +}; + +const debounceWindowStatePersist = (browserWindow, immediate = false) => { + if (!browserWindow || browserWindow.isDestroyed()) return; + const key = String(browserWindow.id); + const revision = (state.windowGeometryRevisions.get(key) || 0) + 1; + state.windowGeometryRevisions.set(key, revision); + + const persist = async () => { + if (state.windowGeometryRevisions.get(key) !== revision) return; + await writeWindowState(browserWindow); + }; + + if (immediate) { + void persist(); + return; + } + + setTimeout(() => { + void persist(); + }, 300); +}; + +const buildHealthUrl = (url) => { + try { + const parsed = new URL(url); + parsed.pathname = `${parsed.pathname.replace(/\/$/, '') || ''}/health`; + return parsed.toString(); + } catch { + return null; + } +}; + +const probeHostWithTimeout = async (url, timeoutMs) => { + const healthUrl = buildHealthUrl(url); + if (!healthUrl) { + throw new Error('Invalid URL'); + } + + const started = Date.now(); + try { + const response = await fetch(healthUrl, { signal: AbortSignal.timeout(timeoutMs) }); + const status = response.status; + return { + status: status >= 200 && status < 300 ? 'ok' : (status === 401 || status === 403 ? 'auth' : 'unreachable'), + latencyMs: Date.now() - started, + }; + } catch { + return { status: 'unreachable', latencyMs: Date.now() - started }; + } +}; + +const waitForHealth = async (url, timeoutMs = 20_000, initialPollMs = 250, maxPollMs = 2000) => { + const deadline = Date.now() + timeoutMs; + let pollMs = initialPollMs; + while (Date.now() < deadline) { + try { + const response = await fetch(buildHealthUrl(url), { signal: AbortSignal.timeout(Math.min(pollMs * 4, 1500)) }); + if (response.ok) { + return true; + } + } catch { + } + await new Promise((resolve) => setTimeout(resolve, pollMs)); + pollMs = Math.min(pollMs * 2, maxPollMs); + } + return false; +}; + +const pickUnusedPort = async () => { + const net = await import('node:net'); + return await new Promise((resolve, reject) => { + const server = net.createServer(); + server.listen(0, '127.0.0.1', () => { + const address = server.address(); + const port = typeof address === 'object' && address ? address.port : 0; + server.close(() => resolve(port)); + }); + server.on('error', reject); + }); +}; + +const isPortFree = async (port) => { + if (!Number.isFinite(port) || port <= 0) return false; + const net = await import('node:net'); + return await new Promise((resolve) => { + const test = net.createServer(); + const done = (value) => { + try { test.close(); } catch {} + resolve(value); + }; + test.once('error', () => done(false)); + test.listen(port, '127.0.0.1', () => done(true)); + }); +}; + +// Return the LAN IPv4 of the interface that routes to the public internet. +// UDP "connect" is a kernel-side route lookup — no packet actually goes out — +// and it picks the same interface as a real outbound connection, which is what +// a phone on the same Wi-Fi needs to reach us. Falls back to scanning +// os.networkInterfaces() if the socket trick fails (e.g. no default route). +const detectLanIPv4Address = async () => { + const ip = await new Promise((resolve) => { + const socket = dgram.createSocket('udp4'); + const finish = (value) => { + try { socket.close(); } catch {} + resolve(value); + }; + socket.once('error', () => finish(null)); + try { + socket.connect(80, '8.8.8.8', (error) => { + if (error) return finish(null); + try { + const addr = socket.address(); + finish(addr && typeof addr.address === 'string' ? addr.address : null); + } catch { + finish(null); + } + }); + } catch { + finish(null); + } + }); + if (ip && ip !== '0.0.0.0' && !ip.startsWith('127.')) return ip; + + for (const entries of Object.values(os.networkInterfaces() || {})) { + for (const entry of entries || []) { + if (entry.family === 'IPv4' && !entry.internal && entry.address) { + return entry.address; + } + } + } + return null; +}; + +const buildLocalUrl = (port) => `http://127.0.0.1:${port}`; + +const resourceRoot = () => isDev ? path.join(__dirname, 'resources') : process.resourcesPath; +const resolveWebDistDir = () => path.join(resourceRoot(), 'web-dist'); + +const normalizeNotificationInput = (raw) => { + if (!raw || typeof raw !== 'object') return {}; + // UI IPC path wraps in { payload: {...} }; sidecar stdout path is flat. + if (raw.payload && typeof raw.payload === 'object') { + return { ...raw, ...raw.payload }; + } + return raw; +}; + +const isAnyWindowFocused = () => + BrowserWindow.getAllWindows().some( + (window) => !window.isDestroyed() && window.isFocused(), + ); + +const focusForegroundWindow = () => { + const windows = BrowserWindow.getAllWindows().filter((window) => !window.isDestroyed()); + if (windows.length === 0) return; + const target = state.mainWindow && !state.mainWindow.isDestroyed() + ? state.mainWindow + : windows.find((window) => window.isVisible()) || windows[0]; + if (target.isMinimized()) target.restore(); + if (!target.isVisible()) target.show(); + target.focus(); + if (process.platform === 'darwin') app.focus({ steal: true }); +}; + +const maybeShowNativeNotification = (rawInput) => { + const payload = normalizeNotificationInput(rawInput); + const requireHidden = Boolean(payload.requireHidden ?? payload.require_hidden); + + if (requireHidden && isAnyWindowFocused()) { + return; + } + + if (!Notification.isSupported()) { + return; + } + + const title = typeof payload.title === 'string' && payload.title.trim() + ? payload.title.trim() + : 'OpenChamber'; + const body = typeof payload.body === 'string' ? payload.body : ''; + const sessionId = typeof payload.sessionId === 'string' && payload.sessionId.trim() + ? payload.sessionId.trim() + : null; + + const notification = new Notification({ + title, + body, + silent: false, + ...(process.platform === 'darwin' ? { sound: 'Glass' } : {}), + }); + + notification.on('click', () => { + focusForegroundWindow(); + if (sessionId) { + emitToAllWindows('openchamber:open-session', { sessionId }); + } + }); + + notification.show(); +}; + +const mapUpdaterProgressEvent = (payload) => ({ + event: payload.event, + data: payload.data, +}); + +const SHELL_ENV_TIMEOUT_MS = 5_000; +let cachedShellEnv = null; +let shellEnvProbed = false; + +const isNushell = (shell) => { + const name = path.basename(shell).toLowerCase(); + return name === 'nu' || name === 'nu.exe'; +}; + +const parseShellEnv = (buf) => { + const result = {}; + for (const line of buf.toString('utf8').split('\0')) { + if (!line) continue; + const idx = line.indexOf('='); + if (idx <= 0) continue; + result[line.slice(0, idx)] = line.slice(idx + 1); + } + return result; +}; + +const probeShellEnv = (shell, mode) => { + const result = spawnSync(shell, [mode, '-c', 'env -0'], { + stdio: ['ignore', 'pipe', 'ignore'], + timeout: SHELL_ENV_TIMEOUT_MS, + windowsHide: true, + }); + if (result.error || result.status !== 0) return null; + const env = parseShellEnv(result.stdout); + return Object.keys(env).length > 0 ? env : null; +}; + +// Finder-launched apps on macOS inherit a minimal PATH (no /opt/homebrew, mise, asdf, etc.). +// Probe the user's login shell once so the sidecar sees the same PATH / tool env as `$SHELL -il`. +const loadShellEnv = () => { + if (shellEnvProbed) return cachedShellEnv; + shellEnvProbed = true; + if (process.platform === 'win32') return null; + const shell = process.env.SHELL || '/bin/sh'; + if (isNushell(shell)) return null; + cachedShellEnv = probeShellEnv(shell, '-il') || probeShellEnv(shell, '-l'); + return cachedShellEnv; +}; + +// Merge the user's login-shell env (PATH, etc.) into this process before we +// import/start the server in-process. The server and its children (opencode +// CLI, git, etc.) inherit process.env directly now — there is no sidecar +// subprocess to hand a custom env to. +const inheritUserShellEnv = () => { + const shellEnv = loadShellEnv(); + if (!shellEnv) return; + + const homeDir = os.homedir(); + const shellPathSegments = typeof shellEnv.PATH === 'string' ? shellEnv.PATH.split(':') : []; + const processPathSegments = typeof process.env.PATH === 'string' ? process.env.PATH.split(':') : []; + const pathSegments = [ + ...shellPathSegments, + '/opt/homebrew/bin', + '/usr/local/bin', + '/usr/bin', + '/bin', + '/usr/sbin', + '/sbin', + path.join(homeDir, '.opencode', 'bin'), + path.join(homeDir, '.local', 'bin'), + path.join(homeDir, '.bun', 'bin'), + path.join(homeDir, '.cargo', 'bin'), + path.join(homeDir, 'bin'), + ...processPathSegments, + ].filter(Boolean); + const uniquePath = Array.from(new Set(pathSegments)).join(':'); + + for (const [key, value] of Object.entries(shellEnv)) { + if (key === 'PATH') continue; + if (typeof process.env[key] === 'undefined') { + process.env[key] = value; + } + } + process.env.PATH = uniquePath; +}; + +const spawnLocalServer = async () => { + inheritUserShellEnv(); + + const settings = readSettingsRoot(); + const storedPort = Number.isFinite(settings.desktopLocalPort) ? settings.desktopLocalPort : null; + // When the user enables "Desktop Network Access" we bind on all interfaces + // so phones/tablets on the same Wi-Fi can reach the app. UI shows a clear + // warning and persists the flag via /api/config/settings. + const lanAccessEnabled = settings.desktopLanAccessEnabled === true; + const bindHost = lanAccessEnabled ? '0.0.0.0' : '127.0.0.1'; + + // Probe before starting the server — main() in the server module sets up a + // lot of global state before binding, and calling it twice after a listen + // failure would double-wire runtimes. Pick a known-free port in one shot. + const candidates = [storedPort, DEFAULT_DESKTOP_PORT].filter((v) => Number.isFinite(v) && v > 0); + let chosenPort = 0; + for (const candidate of candidates) { + if (await isPortFree(candidate)) { + chosenPort = candidate; + break; + } + } + if (chosenPort === 0) { + chosenPort = await pickUnusedPort(); + } + + // The server module reads ENV_DESKTOP_NOTIFY / OPENCHAMBER_DIST_DIR / + // OPENCHAMBER_RUNTIME at import time (top-level const), so these must be + // set before the first import. After this point, the same env is used by + // both the Electron main and the server running inside it. + process.env.OPENCHAMBER_HOST = bindHost; + process.env.OPENCHAMBER_DIST_DIR = resolveWebDistDir(); + process.env.OPENCHAMBER_RUNTIME = 'desktop'; + process.env.OPENCHAMBER_DESKTOP_NOTIFY = 'true'; + process.env.NO_PROXY = process.env.NO_PROXY || 'localhost,127.0.0.1'; + process.env.no_proxy = process.env.no_proxy || 'localhost,127.0.0.1'; + + const { startWebUiServer } = await import('@openchamber/web/server/index.js'); + + const handle = await startWebUiServer({ + port: chosenPort, + host: bindHost, + attachSignals: false, + exitOnShutdown: false, + onDesktopNotification: (payload) => maybeShowNativeNotification(payload), + }); + + const port = handle.getPort(); + const url = buildLocalUrl(port); + + state.serverHandle = handle; + state.sidecarUrl = url; + + const root = readSettingsRoot(); + root.desktopLocalPort = port; + await writeSettingsRoot(root); + + return url; +}; + +const killSidecar = () => { + if (state.serverHandle) { + try { + const result = state.serverHandle.stop({ exitProcess: false }); + if (result && typeof result.then === 'function') { + result.catch(() => {}); + } + } catch { + } + state.serverHandle = null; + } + state.sidecarUrl = null; +}; + +const macosMajorVersion = () => { + if (process.platform !== 'darwin') return 0; + const result = spawnSync('/usr/bin/sw_vers', ['-productVersion'], { encoding: 'utf8' }); + const raw = (result.stdout || '').trim(); + const [majorRaw, minorRaw] = raw.split('.'); + const major = Number.parseInt(majorRaw || '0', 10); + const minor = Number.parseInt(minorRaw || '0', 10); + return major === 10 ? minor : major; +}; + +const buildInitScript = (localOrigin, bootOutcome) => { + const home = JSON.stringify(os.homedir() || ''); + const local = JSON.stringify(localOrigin || ''); + const macVersion = macosMajorVersion(); + const outcome = JSON.stringify(bootOutcome ?? null); + return [ + '(function(){', + `try{window.__OPENCHAMBER_HOME__=${home};window.__OPENCHAMBER_MACOS_MAJOR__=${macVersion};window.__OPENCHAMBER_LOCAL_ORIGIN__=${local};var __oc_bo=${outcome};if(__oc_bo){window.__OPENCHAMBER_DESKTOP_BOOT_OUTCOME__=__oc_bo;}}catch(_e){}`, + '}())', + ].join(''); +}; + +const computeBootOutcome = ({ envTargetUrl, probe, config, localAvailable }) => { + if (envTargetUrl) { + const status = probe && probe.status === 'unreachable' ? 'unreachable' : 'ok'; + return { target: 'remote', status, hostId: ENV_OVERRIDE_HOST_ID, url: envTargetUrl }; + } + + const defaultId = config.defaultHostId || ''; + if (!defaultId) { + return { target: null, status: 'not-configured' }; + } + + if (defaultId === LOCAL_HOST_ID) { + return localAvailable + ? { target: 'local', status: 'ok' } + : { target: 'local', status: 'unreachable' }; + } + + const host = config.hosts.find((entry) => entry.id === defaultId); + if (!host) { + return { target: 'remote', status: 'missing', hostId: defaultId }; + } + + const status = probe && probe.status === 'unreachable' ? 'unreachable' : 'ok'; + return { target: 'remote', status, hostId: host.id, url: host.url }; +}; + +const buildStartupSplashHtml = () => { + const settings = readSettingsRoot(); + const splashBgLight = typeof settings.splashBgLight === 'string' ? settings.splashBgLight.trim() : '#f5f5f4'; + const splashFgLight = typeof settings.splashFgLight === 'string' ? settings.splashFgLight.trim() : '#1c1917'; + const splashBgDark = typeof settings.splashBgDark === 'string' ? settings.splashBgDark.trim() : '#0c0a09'; + const splashFgDark = typeof settings.splashFgDark === 'string' ? settings.splashFgDark.trim() : '#fafaf9'; + + return ` + + + + + + + +
OpenChamber
+ + `; +}; + +const isBenignNavigationAbort = (error) => { + if (!error || typeof error !== 'object') { + return false; + } + + if (error.errno === -3) { + return true; + } + + const message = typeof error.message === 'string' ? error.message : ''; + return message.includes('ERR_ABORTED') || message.includes(' (-3) loading '); +}; + +const navigateWindow = async (browserWindow, url, { allowAbort = false } = {}) => { + try { + await browserWindow.loadURL(url); + } catch (error) { + if (allowAbort && isBenignNavigationAbort(error)) { + return; + } + throw error; + } +}; + +const emitToWindow = (browserWindow, event, detail) => { + if (!browserWindow || browserWindow.isDestroyed()) return; + browserWindow.webContents.send('openchamber:emit', { event, detail }); +}; + +const emitToAllWindows = (event, detail) => { + for (const browserWindow of BrowserWindow.getAllWindows()) { + emitToWindow(browserWindow, event, detail); + } +}; + +const pendingDeepLinks = []; + +const parseDeepLink = (raw) => { + if (typeof raw !== 'string') return null; + const trimmed = raw.trim(); + if (!trimmed) return null; + try { + const url = new URL(trimmed); + if (url.protocol !== `${DEEP_LINK_PROTOCOL}:`) return null; + const type = url.hostname; + if (!type) return null; + const segments = url.pathname.split('/').filter(Boolean); + const value = segments.length > 0 + ? decodeURIComponent(segments.join('/')) + : ''; + return { type, value }; + } catch { + return null; + } +}; + +const switchToHostById = async (rawId) => { + const id = typeof rawId === 'string' ? rawId.trim() : ''; + if (!id) return; + const config = readDesktopHostsConfig(); + let targetUrl = null; + if (id === LOCAL_HOST_ID) { + targetUrl = state.sidecarUrl || state.localOrigin; + } else { + const host = config.hosts.find((entry) => entry.id === id); + if (!host) { + log.warn('[electron] deep-link host not found:', id); + return; + } + targetUrl = host.url; + } + if (!targetUrl) { + log.warn('[electron] deep-link host has no target URL:', id); + return; + } + const bootOutcome = id === LOCAL_HOST_ID + ? { target: 'local', status: 'ok' } + : { target: 'remote', status: 'ok', hostId: id, url: targetUrl }; + log.info('[electron] switching to host', { id, bootOutcome }); + await activateMainWindow(targetUrl, state.localOrigin, bootOutcome); +}; + +const dispatchDeepLink = (link) => { + if (!link) return; + log.info('[electron] dispatching deep-link', { type: link.type, valueLen: link.value?.length || 0 }); + if (link.type === 'session' && link.value) { + emitToAllWindows('openchamber:open-session', { sessionId: link.value }); + return; + } + if (link.type === 'project' && link.value) { + emitToAllWindows('openchamber:open-project', { projectPath: link.value }); + return; + } + if (link.type === 'host' && link.value) { + void switchToHostById(link.value); + return; + } + log.warn('[electron] unknown deep-link action:', link.type); +}; + +const flushPendingDeepLinks = () => { + while (pendingDeepLinks.length > 0) { + dispatchDeepLink(pendingDeepLinks.shift()); + } +}; + +const isMainWindowReadyForDeepLink = () => + Boolean(state.mainWindow) + && !state.mainWindow.isDestroyed() + && !state.mainWindow.webContents.isLoading(); + +const handleDeepLinks = (urls) => { + for (const raw of urls) { + const parsed = parseDeepLink(raw); + if (!parsed) continue; + if (isMainWindowReadyForDeepLink()) { + dispatchDeepLink(parsed); + } else { + pendingDeepLinks.push(parsed); + } + } +}; + +const extractInitialDeepLinks = () => + process.argv.filter((arg) => typeof arg === 'string' && arg.startsWith(`${DEEP_LINK_PROTOCOL}://`)); + +const dispatchDomEventToWindow = (browserWindow, event, detail) => { + if (!browserWindow || browserWindow.isDestroyed()) return; + + const eventLiteral = JSON.stringify(event); + const script = detail === undefined + ? `window.dispatchEvent(new Event(${eventLiteral}));` + : `window.dispatchEvent(new CustomEvent(${eventLiteral}, { detail: ${JSON.stringify(detail)} }));`; + + void browserWindow.webContents.executeJavaScript(script, true).catch(() => {}); +}; + +const getMenuTargetWindow = () => { + const focused = BrowserWindow.getFocusedWindow(); + if (focused && !focused.isDestroyed()) return focused; + if (state.mainWindow && !state.mainWindow.isDestroyed()) return state.mainWindow; + const [firstWindow] = BrowserWindow.getAllWindows(); + return firstWindow && !firstWindow.isDestroyed() ? firstWindow : null; +}; + +const dispatchMenuAction = (action) => { + const target = getMenuTargetWindow(); + emitToWindow(target, 'openchamber:menu-action', action); + dispatchDomEventToWindow(target, 'openchamber:menu-action', action); +}; + +const dispatchCheckForUpdates = () => { + emitToAllWindows('openchamber:check-for-updates'); + for (const browserWindow of BrowserWindow.getAllWindows()) { + dispatchDomEventToWindow(browserWindow, 'openchamber:check-for-updates'); + } +}; + +const nextWindowLabel = () => { + const value = state.windowCounter++; + return value === 1 ? 'main' : `main-${value}`; +}; + +const readThemeSource = () => { + const settings = readSettingsRoot(); + if (settings.useSystemTheme === true) return 'system'; + if (settings.themeMode === 'light' || settings.themeVariant === 'light') return 'light'; + if (settings.themeMode === 'dark' || settings.themeVariant === 'dark') return 'dark'; + return 'system'; +}; + +const createBrowserWindow = ({ label, restoreGeometry, url }) => { + const saved = restoreGeometry ? readWindowState() : null; + const useSaved = saved && typeof saved.width === 'number' && typeof saved.height === 'number'; + const desktopLocalOrigin = state.localOrigin || ''; + const desktopHome = os.homedir() || ''; + const desktopMacosMajor = String(macosMajorVersion()); + const options = { + title: 'OpenChamber', + width: useSaved ? Math.max(saved.width, MIN_RESTORE_WINDOW_WIDTH) : 1280, + height: useSaved ? Math.max(saved.height, MIN_RESTORE_WINDOW_HEIGHT) : 800, + minWidth: MIN_WINDOW_WIDTH, + minHeight: MIN_WINDOW_HEIGHT, + show: false, + backgroundColor: '#151313', + // Tauri used an overlay title bar with explicit traffic-light placement. + // Electron's hiddenInset adds its own extra inset, which leaves the controls + // visibly lower than the app header. Use a plain hidden title bar instead. + titleBarStyle: process.platform === 'darwin' ? 'hidden' : 'default', + trafficLightPosition: process.platform === 'darwin' ? { x: 16, y: 18 } : undefined, + webPreferences: { + additionalArguments: [ + `--openchamber-local-origin=${desktopLocalOrigin}`, + `--openchamber-home=${desktopHome}`, + `--openchamber-macos-major=${desktopMacosMajor}`, + `--openchamber-boot-outcome=${JSON.stringify(state.bootOutcome || null)}`, + ], + preload: isDev ? path.join(__dirname, 'preload.mjs') : path.join(app.getAppPath(), 'preload.mjs'), + backgroundThrottling: true, + contextIsolation: true, + nodeIntegration: false, + // sandbox must stay off: the preload uses contextBridge + ipcRenderer + // from Electron's Node layer. contextIsolation + nodeIntegration:false + // keep the renderer world walled off from Node. Do NOT flip to true — + // the preload would fail to load and __TAURI__ would go undefined. + sandbox: false, + }, + }; + + const browserWindow = new BrowserWindow(options); + browserWindow.__ocLabel = label || nextWindowLabel(); + + if (useSaved && Number.isFinite(saved.x) && Number.isFinite(saved.y)) { + browserWindow.setPosition(saved.x, saved.y); + } + + if (useSaved && saved.maximized) { + browserWindow.maximize(); + } + + browserWindow.on('focus', () => { + state.focusedWindowIds.add(browserWindow.id); + }); + browserWindow.on('blur', () => { + state.focusedWindowIds.delete(browserWindow.id); + }); + browserWindow.on('resize', () => { + emitToWindow(browserWindow, 'openchamber:window-resized'); + debounceWindowStatePersist(browserWindow, false); + }); + browserWindow.on('move', () => { + debounceWindowStatePersist(browserWindow, false); + }); + browserWindow.on('close', (event) => { + if (process.platform === 'darwin' && !state.quitRequested) { + const remainingVisible = BrowserWindow.getAllWindows().filter( + (window) => !window.isDestroyed() && window.isVisible(), + ).length; + + if (remainingVisible <= 1) { + debounceWindowStatePersist(browserWindow, true); + event.preventDefault(); + browserWindow.hide(); + return; + } + } + + debounceWindowStatePersist(browserWindow, true); + }); + browserWindow.on('closed', () => { + state.focusedWindowIds.delete(browserWindow.id); + if (state.mainWindow && browserWindow.id === state.mainWindow.id) { + state.mainWindow = null; + } + if (BrowserWindow.getAllWindows().length === 0) { + killSidecar(); + if (process.platform !== 'darwin') { + app.quit(); + } + } + }); + + // Any navigation target that isn't our own UI (local server / configured + // desktop hosts) should open in the user's default browser, not spawn + // another Electron window loading arbitrary web content. + const isAllowedNavigationUrl = (raw) => { + try { + const url = new URL(raw); + if (url.protocol === 'file:' || url.protocol === 'about:' || url.protocol === 'devtools:') return true; + if (url.protocol !== 'http:' && url.protocol !== 'https:') return false; + const hostname = url.hostname; + if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1') return true; + if (state.localOrigin) { + try { + if (new URL(state.localOrigin).origin === url.origin) return true; + } catch { + } + } + const hosts = readDesktopHostsConfig()?.hosts || []; + for (const entry of hosts) { + if (typeof entry?.url !== 'string') continue; + try { + if (new URL(entry.url).origin === url.origin) return true; + } catch { + } + } + return false; + } catch { + return false; + } + }; + + browserWindow.webContents.setWindowOpenHandler(({ url }) => { + if (isAllowedNavigationUrl(url)) { + return { action: 'allow' }; + } + void shell.openExternal(url).catch(() => {}); + return { action: 'deny' }; + }); + + browserWindow.webContents.on('will-navigate', (event, url) => { + if (isAllowedNavigationUrl(url)) return; + event.preventDefault(); + void shell.openExternal(url).catch(() => {}); + }); + + browserWindow.webContents.setZoomFactor(1); + browserWindow.webContents.on('zoom-changed', () => { + browserWindow.webContents.setZoomFactor(1); + }); + + browserWindow.webContents.on('dom-ready', () => { + if (state.initScript) { + void browserWindow.webContents.executeJavaScript(state.initScript).catch(() => {}); + } + }); + + browserWindow.webContents.on('did-finish-load', () => { + browserWindow.webContents.setZoomFactor(1); + if (state.mainWindow && browserWindow.id === state.mainWindow.id && pendingDeepLinks.length > 0) { + const timer = setTimeout(flushPendingDeepLinks, 400); + if (typeof timer?.unref === 'function') timer.unref(); + } + }); + + browserWindow.once('ready-to-show', () => { + browserWindow.show(); + browserWindow.focus(); + }); + + if (url) { + void navigateWindow(browserWindow, url); + } else { + void navigateWindow( + browserWindow, + `data:text/html;charset=utf-8,${encodeURIComponent(buildStartupSplashHtml())}`, + { allowAbort: true }, + ); + } + + return browserWindow; +}; + +const activateMainWindow = async (url, localOrigin, bootOutcome) => { + state.localOrigin = localOrigin; + state.bootOutcome = bootOutcome ?? null; + state.initScript = buildInitScript(localOrigin, state.bootOutcome); + + const mainWindow = state.mainWindow; + if (mainWindow && !mainWindow.isDestroyed()) { + await navigateWindow(mainWindow, url, { allowAbort: true }); + mainWindow.show(); + mainWindow.focus(); + return mainWindow; + } + + state.mainWindow = createBrowserWindow({ + label: 'main', + restoreGeometry: true, + url, + }); + return state.mainWindow; +}; + +const createAdditionalWindow = async (url) => { + if (!state.localOrigin) { + return null; + } + const browserWindow = createBrowserWindow({ + label: nextWindowLabel(), + restoreGeometry: false, + url, + }); + return browserWindow; +}; + +const resolveInitialUrl = async () => { + const localUrl = isDev && await waitForHealth('http://127.0.0.1:3901', 5_000, 100) + ? 'http://127.0.0.1:3901' + : await spawnLocalServer(); + + const localUiUrl = isDev && await waitForHealth('http://127.0.0.1:5173', 8_000, 100) + ? 'http://127.0.0.1:5173' + : localUrl; + + state.sidecarUrl = localUrl; + const localAvailable = Boolean(localUrl); + + const localOrigin = new URL(localUiUrl).origin; + let initialUrl = localUiUrl; + let remoteProbe = null; + + const envTarget = normalizeHostUrl(process.env.OPENCHAMBER_SERVER_URL || ''); + const config = readDesktopHostsConfig(); + if (envTarget) { + initialUrl = envTarget; + } else if (config.defaultHostId && config.defaultHostId !== LOCAL_HOST_ID) { + const host = config.hosts.find((entry) => entry.id === config.defaultHostId); + if (host?.url) { + initialUrl = host.url; + } + } + + if (initialUrl !== localUiUrl) { + remoteProbe = await probeHostWithTimeout(initialUrl, 2_000); + if (remoteProbe.status === 'unreachable') { + remoteProbe = await probeHostWithTimeout(initialUrl, 10_000); + } + if (remoteProbe.status === 'unreachable') { + state.unreachableHosts.add(initialUrl); + initialUrl = localUiUrl; + } + } + + const bootOutcome = computeBootOutcome({ + envTargetUrl: envTarget || null, + probe: remoteProbe, + config, + localAvailable, + }); + + return { initialUrl, localOrigin, localUiUrl, bootOutcome }; +}; + +const compareSemver = (left, right) => { + const a = String(left || '').replace(/^v/, '').split('.').map((value) => Number.parseInt(value || '0', 10)); + const b = String(right || '').replace(/^v/, '').split('.').map((value) => Number.parseInt(value || '0', 10)); + const length = Math.max(a.length, b.length); + for (let index = 0; index < length; index += 1) { + const diff = (a[index] || 0) - (b[index] || 0); + if (diff !== 0) return diff; + } + return 0; +}; + +const parseGithubRepo = () => { + return { owner: 'btriapitsyn', repo: 'openchamber' }; +}; + +const setupAutoUpdater = () => { + if (!app.isPackaged) { + return; + } + autoUpdater.autoDownload = false; + autoUpdater.autoInstallOnAppQuit = false; + autoUpdater.allowPrerelease = false; + autoUpdater.fullChangelog = true; + autoUpdater.disableWebInstaller = false; + autoUpdater.logger = log; + + const { owner, repo } = parseGithubRepo(); + autoUpdater.setFeedURL({ + provider: 'github', + owner, + repo, + }); + + autoUpdater.on('download-progress', (progress) => { + emitToAllWindows('openchamber:update-progress', mapUpdaterProgressEvent({ + event: 'Progress', + data: { + chunkLength: Math.max(0, Math.round(progress.bytesPerSecond || 0)), + downloaded: Math.round(progress.transferred || 0), + total: Math.round(progress.total || 0), + }, + })); + }); +}; + +const parseRelevantChangelogNotes = async (fromVersion, toVersion) => { + try { + const response = await fetch(CHANGELOG_URL, { signal: AbortSignal.timeout(10_000) }); + if (!response.ok) return null; + const changelog = await response.text(); + const sections = changelog.split(/^##\s+\[/m).slice(1); + const relevant = []; + for (const section of sections) { + const version = section.split(']')[0]; + if (compareSemver(version, fromVersion) > 0 && compareSemver(version, toVersion) <= 0) { + relevant.push(`## [${section}`.trim()); + } + } + return relevant.length > 0 ? relevant.join('\n\n') : null; + } catch { + return null; + } +}; + +const buildInstalledAppsCachePath = () => path.join(path.dirname(settingsFilePath()), INSTALLED_APPS_CACHE_FILE); + +// Async variants. sips + mdfind via spawnSync blocked the Electron main event +// loop for 2-3s on boot (22 OPEN_IN_APPS × ~200 ms each). Use execFile promises +// so each child-process wait yields to the loop and the UI stays responsive. +const pathExists = async (candidate) => { + try { + await fsp.access(candidate); + return true; + } catch { + return false; + } +}; + +const resolveAppBundlePath = async (appName) => { + if (process.platform !== 'darwin') return null; + const bundleName = appName.endsWith('.app') ? appName : `${appName}.app`; + const candidates = [ + `/Applications/${bundleName}`, + `/System/Applications/${bundleName}`, + `/System/Applications/Utilities/${bundleName}`, + path.join(os.homedir(), 'Applications', bundleName), + ]; + for (const candidate of candidates) { + if (await pathExists(candidate)) return candidate; + } + try { + const { stdout } = await execFileAsync('mdfind', ['-name', bundleName], { encoding: 'utf8' }); + const first = (stdout || '').split('\n').map((line) => line.trim()).find(Boolean); + return first || null; + } catch { + return null; + } +}; + +const isAppBundleInstalled = async (appName) => Boolean(await resolveAppBundlePath(appName)); + +const iconToDataUrl = async (iconPath, appName) => { + if (!iconPath || !(await pathExists(iconPath))) return null; + const safeName = String(appName || 'app').replace(/[^a-z0-9]/gi, '_'); + const tempPath = path.join(os.tmpdir(), `openchamber-icon-${safeName}-${Date.now()}.png`); + try { + await execFileAsync('sips', ['-s', 'format', 'png', '-Z', '32', iconPath, '--out', tempPath], { stdio: 'ignore' }); + } catch { + return null; + } + if (!(await pathExists(tempPath))) return null; + try { + const bytes = await fsp.readFile(tempPath); + return `data:image/png;base64,${bytes.toString('base64')}`; + } finally { + await fsp.rm(tempPath, { force: true }).catch(() => {}); + } +}; + +const resolveAppIconPath = async (appPath) => { + if (!appPath || !(await pathExists(appPath))) return null; + const resourcesPath = path.join(appPath, 'Contents', 'Resources'); + if (!(await pathExists(resourcesPath))) return null; + let entries; + try { + entries = await fsp.readdir(resourcesPath); + } catch { + return null; + } + const icon = entries.find((entry) => entry.toLowerCase().endsWith('.icns')); + return icon ? path.join(resourcesPath, icon) : null; +}; + +const buildInstalledApps = async (apps) => { + const seen = new Set(); + const names = apps + .map((raw) => String(raw || '').trim()) + .filter((raw) => raw && !seen.has(raw) && seen.add(raw)); + const results = []; + for (const name of names) { + const appPath = await resolveAppBundlePath(name); + if (!appPath) continue; + const iconDataUrl = await iconToDataUrl(await resolveAppIconPath(appPath), name); + results.push({ name, iconDataUrl }); + } + return results; +}; + +const parseSshConfigImports = () => { + const sshConfigPath = path.join(os.homedir(), '.ssh', 'config'); + if (!fs.existsSync(sshConfigPath)) return []; + const lines = fs.readFileSync(sshConfigPath, 'utf8').split(/\r?\n/); + const results = []; + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith('#') || !trimmed.toLowerCase().startsWith('host ')) { + continue; + } + const hosts = trimmed.slice(5).trim().split(/\s+/).filter(Boolean); + for (const host of hosts) { + results.push({ + host, + pattern: /[*?]/.test(host), + source: sshConfigPath, + sshCommand: `ssh ${host}`, + }); + } + } + return results; +}; + +const readDesktopSshInstances = () => { + const root = readSettingsRoot(); + return { instances: Array.isArray(root.desktopSshInstances) ? root.desktopSshInstances : [] }; +}; + +const writeDesktopSshInstances = async (config) => { + const root = readSettingsRoot(); + root.desktopSshInstances = Array.isArray(config?.instances) ? config.instances : []; + await writeSettingsRoot(root); + return { instances: root.desktopSshInstances }; +}; + +const updateHostUrlForSshInstance = async (id, label, localUrl) => { + const config = readDesktopHostsConfig(); + const nextHosts = config.hosts.filter((entry) => entry.id !== id); + nextHosts.push({ id, label, url: localUrl }); + await writeDesktopHostsConfig({ hosts: nextHosts, defaultHostId: config.defaultHostId }); +}; + +const JETBRAINS_APP_IDS = new Set([ + 'pycharm', + 'intellij', + 'webstorm', + 'phpstorm', + 'rider', + 'rustrover', + 'android-studio', +]); + +const CLI_BY_APP_ID = { + vscode: 'code', + cursor: 'cursor', + vscodium: 'codium', + windsurf: 'windsurf', + zed: 'zed', +}; + +const buildOpenProjectSpecs = ({ projectPath, appId, appName }) => { + if (appId === 'finder') { + return [{ program: 'open', args: [projectPath] }]; + } + + if (appId === 'terminal' || appId === 'iterm2' || appId === 'ghostty') { + return [{ program: 'open', args: ['-a', appName, projectPath] }]; + } + + const specs = []; + + const cli = CLI_BY_APP_ID[appId]; + if (cli) { + specs.push({ program: cli, args: ['-n', projectPath] }); + } + + if (JETBRAINS_APP_IDS.has(appId)) { + specs.push({ program: 'open', args: ['-na', appName, '--args', projectPath] }); + } + + specs.push({ program: 'open', args: ['-a', appName, projectPath] }); + return specs; +}; + +const buildOpenFileSpecs = ({ filePath, appId, appName }) => { + if (appId === 'finder') { + return [{ program: 'open', args: ['-R', filePath] }]; + } + + const parentDir = path.dirname(filePath); + if (appId === 'terminal' || appId === 'iterm2' || appId === 'ghostty') { + return [{ program: 'open', args: ['-a', appName, parentDir] }]; + } + + const specs = []; + + const cli = CLI_BY_APP_ID[appId]; + if (cli) { + specs.push({ program: cli, args: [filePath] }); + } + + specs.push({ program: 'open', args: ['-a', appName, filePath] }); + return specs; +}; + +const runSpecChain = (specs, appName) => { + const failures = []; + for (const spec of specs) { + const result = spawnSync(spec.program, spec.args, { stdio: 'ignore' }); + if (result.error) { + failures.push(`${spec.program}: ${result.error.message}`); + continue; + } + if (result.status === 0) { + return; + } + failures.push(`${spec.program} exited ${result.status}`); + } + throw new Error(`Failed to open in ${appName}: ${failures.join('; ')}`); +}; + +const handleInvoke = async (browserWindow, command, args = {}) => { + switch (command) { + case 'desktop_start_window_drag': + return null; + + case 'desktop_is_window_fullscreen': + return Boolean(browserWindow?.isFullScreen()); + + case 'desktop_set_window_title': + if (browserWindow && typeof args.title === 'string') { + browserWindow.setTitle(args.title); + } + return null; + + case 'desktop_get_app_version': + return APP_VERSION; + + case 'desktop_save_markdown_file': { + const defaultPath = typeof args.defaultFileName === 'string' ? args.defaultFileName.trim() : ''; + if (!defaultPath) { + throw new Error('Default file name is required'); + } + + const content = typeof args.content === 'string' ? args.content : ''; + const result = await dialog.showSaveDialog(browserWindow || undefined, { + defaultPath, + filters: [{ name: 'Markdown', extensions: ['md'] }], + }); + if (result.canceled || !result.filePath) { + return null; + } + + await fsp.writeFile(result.filePath, content, 'utf8'); + return result.filePath; + } + + case 'desktop_read_file': { + const rawPath = typeof args.path === 'string' ? args.path : ''; + if (!rawPath) throw new Error('Path is required'); + // Defense in depth behind the IPC origin gate: even our own UI (or a + // prompt-injected agent) can't read credential stores. Resolve the + // path, require it under $HOME or tmpdir, and refuse known secret dirs + // / dotfiles commonly holding keys. + const filePath = path.resolve(rawPath); + const home = os.homedir() || ''; + const tmp = os.tmpdir() || ''; + const underHome = home && (filePath === home || filePath.startsWith(home + path.sep)); + const underTmp = tmp && (filePath === tmp || filePath.startsWith(tmp + path.sep)); + if (!underHome && !underTmp) { + throw new Error('File is outside the allowed workspace'); + } + const DENIED_SEGMENTS = ['.ssh', '.aws', '.gnupg', '.gpg', '.config/gh', '.config/openchamber/credentials']; + const relFromHome = underHome ? filePath.slice(home.length + 1) : ''; + const relNormalized = relFromHome.split(path.sep).join('/'); + if (DENIED_SEGMENTS.some((segment) => relNormalized === segment || relNormalized.startsWith(`${segment}/`))) { + throw new Error('Access to this path is not allowed'); + } + const basename = path.basename(filePath).toLowerCase(); + if (basename === '.env' || basename.startsWith('.env.') || basename.endsWith('.pem') || basename.endsWith('.key')) { + throw new Error('Access to this path is not allowed'); + } + const stats = await fsp.stat(filePath); + if (stats.size > 50 * 1024 * 1024) { + throw new Error('File is too large. Maximum size is 50MB.'); + } + const bytes = await fsp.readFile(filePath); + const ext = path.extname(filePath).toLowerCase(); + const mime = ({ + '.png': 'image/png', + '.jpg': 'image/jpeg', + '.jpeg': 'image/jpeg', + '.gif': 'image/gif', + '.webp': 'image/webp', + '.svg': 'image/svg+xml', + '.bmp': 'image/bmp', + '.ico': 'image/x-icon', + '.pdf': 'application/pdf', + '.txt': 'text/plain', + '.md': 'text/markdown', + '.json': 'application/json', + '.js': 'text/javascript', + '.ts': 'text/typescript', + '.tsx': 'text/typescript-jsx', + '.jsx': 'text/javascript-jsx', + '.html': 'text/html', + '.css': 'text/css', + '.py': 'text/x-python', + })[ext] || 'application/octet-stream'; + return { mime, base64: bytes.toString('base64'), size: bytes.length }; + } + + case 'desktop_notify': + maybeShowNativeNotification(args); + return null; + + case 'desktop_clear_cache': + await session.defaultSession.clearStorageData(); + for (const browserWindow of BrowserWindow.getAllWindows()) { + browserWindow.webContents.reload(); + } + return null; + + case 'desktop_open_path': { + const targetPath = typeof args.path === 'string' ? args.path.trim() : ''; + const appName = typeof args.app === 'string' ? args.app.trim() : ''; + if (!targetPath) throw new Error('Path is required'); + if (process.platform === 'darwin') { + const openArgs = appName ? ['-a', appName, targetPath] : [targetPath]; + spawn('open', openArgs, { detached: true, stdio: 'ignore' }).unref(); + return null; + } + await shell.openPath(targetPath); + return null; + } + + case 'desktop_reveal_path': { + const targetPath = typeof args.path === 'string' ? args.path.trim() : ''; + if (!targetPath) { + throw new Error('Path is required'); + } + + const stats = await fsp.stat(targetPath).catch(() => null); + if (stats?.isDirectory()) { + await shell.openPath(targetPath); + return null; + } + + shell.showItemInFolder(targetPath); + return null; + } + + case 'desktop_open_in_app': { + if (process.platform !== 'darwin') { + throw new Error('desktop_open_in_app is only supported on macOS'); + } + const projectPath = typeof args.projectPath === 'string' ? args.projectPath.trim() : ''; + const appId = typeof args.appId === 'string' ? args.appId.trim().toLowerCase() : ''; + const appName = typeof args.appName === 'string' ? args.appName.trim() : ''; + if (!projectPath || !appId || !appName) { + throw new Error('Project path, app id, and app name are required'); + } + runSpecChain(buildOpenProjectSpecs({ projectPath, appId, appName }), appName); + return null; + } + + case 'desktop_open_file_in_app': { + if (process.platform !== 'darwin') { + throw new Error('desktop_open_file_in_app is only supported on macOS'); + } + const filePath = typeof args.filePath === 'string' ? args.filePath.trim() : ''; + const appId = typeof args.appId === 'string' ? args.appId.trim().toLowerCase() : ''; + const appName = typeof args.appName === 'string' ? args.appName.trim() : ''; + if (!filePath || !appId || !appName) { + throw new Error('File path, app id, and app name are required'); + } + runSpecChain(buildOpenFileSpecs({ filePath, appId, appName }), appName); + return null; + } + + case 'desktop_filter_installed_apps': { + if (process.platform !== 'darwin') { + throw new Error('desktop_filter_installed_apps is only supported on macOS'); + } + if (!Array.isArray(args.apps)) return []; + const results = await Promise.all( + args.apps.map(async (appName) => (await isAppBundleInstalled(String(appName))) ? String(appName) : null) + ); + return results.filter(Boolean); + } + + case 'desktop_fetch_app_icons': { + if (process.platform !== 'darwin') { + throw new Error('desktop_fetch_app_icons is only supported on macOS'); + } + const names = Array.isArray(args.apps) ? args.apps : []; + const results = []; + for (const name of names) { + const appPath = await resolveAppBundlePath(String(name)); + if (!appPath) continue; + const dataUrl = await iconToDataUrl(await resolveAppIconPath(appPath), String(name)); + if (dataUrl) results.push({ app: String(name), dataUrl }); + } + return results; + } + + case 'desktop_get_installed_apps': { + if (process.platform !== 'darwin') { + throw new Error('desktop_get_installed_apps is only supported on macOS'); + } + const cachePath = buildInstalledAppsCachePath(); + const now = Math.floor(Date.now() / 1000); + let cache = null; + try { + cache = JSON.parse(await fsp.readFile(cachePath, 'utf8')); + } catch { + } + const cachedApps = Array.isArray(cache?.apps) ? cache.apps : []; + const hasCache = Boolean(cache); + const isCacheStale = !cache || (now - Number(cache.updatedAt || 0)) > INSTALLED_APPS_CACHE_TTL_SECS; + const refresh = async () => { + const apps = await buildInstalledApps(Array.isArray(args.apps) ? args.apps : []); + await fsp.mkdir(path.dirname(cachePath), { recursive: true }); + await fsp.writeFile(cachePath, JSON.stringify({ updatedAt: now, apps }, null, 2)); + emitToAllWindows('openchamber:installed-apps-updated', apps); + }; + if (!hasCache || isCacheStale || args.force === true) { + void refresh(); + } + return { apps: cachedApps, hasCache, isCacheStale }; + } + + case 'desktop_hosts_get': + return readDesktopHostsConfig(); + + case 'desktop_hosts_set': { + await writeDesktopHostsConfig(args.input || args.config || {}); + const updatedConfig = readDesktopHostsConfig(); + const envTarget = normalizeHostUrl(process.env.OPENCHAMBER_SERVER_URL || ''); + state.bootOutcome = computeBootOutcome({ + envTargetUrl: envTarget || null, + probe: null, + config: updatedConfig, + localAvailable: Boolean(state.sidecarUrl || state.localOrigin), + }); + state.initScript = buildInitScript(state.localOrigin, state.bootOutcome); + log.info('[electron] hosts config updated, recomputed bootOutcome', state.bootOutcome); + return null; + } + + case 'desktop_host_probe': + return probeHostWithTimeout(String(args.url || ''), 2_000); + + case 'desktop_set_window_theme': { + const mode = typeof args.themeMode === 'string' ? args.themeMode : ''; + const variant = typeof args.themeVariant === 'string' ? args.themeVariant : ''; + nativeTheme.themeSource = mode === 'dark' || variant === 'dark' + ? 'dark' + : (mode === 'light' || variant === 'light' ? 'light' : 'system'); + return null; + } + + case 'desktop_set_vibrancy': { + // Vibrancy (macOS blur) is not supported in the Electron shell — the + // Tauri build used NSVisualEffectView via Tauri plugin, Electron has + // no equivalent for our titleBarStyle:'hidden' setup. Persist the + // disabled state so settings UI reflects it; args.enabled is ignored. + const root = readSettingsRoot(); + root.desktopVibrancy = false; + await writeSettingsRoot(root); + return { enabled: false, requiresRestart: false }; + } + + case 'desktop_check_for_updates': { + const currentVersion = APP_VERSION; + let payload = null; + try { + const response = await fetch(UPDATE_METADATA_URL, { signal: AbortSignal.timeout(10_000) }); + payload = await response.json(); + } catch { + } + + let updateResult = null; + try { + updateResult = await autoUpdater.checkForUpdates(); + } catch { + } + + const updateInfo = updateResult?.updateInfo; + const nextVersion = + (typeof updateInfo?.version === 'string' && updateInfo.version) || + (typeof payload?.version === 'string' && payload.version) || + currentVersion; + const available = compareSemver(nextVersion, currentVersion) > 0; + const body = + (typeof payload?.notes === 'string' && payload.notes.trim() ? payload.notes : null) || + (typeof updateInfo?.releaseNotes === 'string' && updateInfo.releaseNotes.trim() ? updateInfo.releaseNotes : null) || + await parseRelevantChangelogNotes(currentVersion, nextVersion); + state.pendingUpdate = available ? { version: nextVersion, metadata: payload, electronUpdate: updateResult } : null; + return { + available, + currentVersion, + version: available ? nextVersion : null, + body: body || null, + date: + (typeof updateInfo?.releaseDate === 'string' && updateInfo.releaseDate) || + (typeof payload?.pub_date === 'string' ? payload.pub_date : null), + }; + } + + case 'desktop_download_and_install_update': + if (!state.pendingUpdate) { + throw new Error('No pending update'); + } + emitToAllWindows('openchamber:update-progress', mapUpdaterProgressEvent({ + event: 'Started', + data: { + contentLength: null, + }, + })); + if (!state.pendingUpdate.electronUpdate) { + throw new Error('Electron updater metadata is not available for this build'); + } + await autoUpdater.downloadUpdate(); + state.pendingUpdate.downloaded = true; + emitToAllWindows('openchamber:update-progress', mapUpdaterProgressEvent({ + event: 'Finished', + data: {}, + })); + return null; + + case 'desktop_restart': + if (state.pendingUpdate?.downloaded && app.isPackaged) { + autoUpdater.quitAndInstall(false, true); + return null; + } + app.relaunch(); + app.exit(0); + return null; + + case 'desktop_get_lan_address': + return await detectLanIPv4Address(); + + case 'desktop_new_window': { + const config = readDesktopHostsConfig(); + const localUiUrl = state.sidecarUrl || state.localOrigin; + let targetUrl = localUiUrl; + if (config.defaultHostId && config.defaultHostId !== LOCAL_HOST_ID) { + const host = config.hosts.find((entry) => entry.id === config.defaultHostId); + if (host?.url && !state.unreachableHosts.has(host.url)) { + targetUrl = host.url; + } + } + await createAdditionalWindow(targetUrl); + return null; + } + + case 'desktop_new_window_at_url': { + const targetUrl = normalizeHostUrl(String(args.url || '')); + if (!targetUrl) { + throw new Error('Invalid URL'); + } + await createAdditionalWindow(targetUrl); + return null; + } + + case 'desktop_ssh_instances_get': + return sshManager.readInstances(); + + case 'desktop_ssh_instances_set': + await sshManager.setInstances(args.config || {}); + return null; + + case 'desktop_ssh_import_hosts': + return await sshManager.importHosts(); + + case 'desktop_ssh_connect': { + const id = String(args.id || '').trim(); + await sshManager.connect(id); + return null; + } + + case 'desktop_ssh_disconnect': { + const id = String(args.id || '').trim(); + await sshManager.disconnect(id); + return null; + } + + case 'desktop_ssh_status': { + const id = String(args.id || '').trim(); + return await sshManager.statusesWithDefaults(id || undefined); + } + + case 'desktop_ssh_logs': + return sshManager.logsForInstance(String(args.id || '').trim(), Number(args.limit) || 200); + + case 'desktop_ssh_logs_clear': + sshManager.clearLogsForInstance(String(args.id || '').trim()); + return null; + + default: + throw new Error(`Unknown desktop command: ${command}`); + } +}; + +const buildMacMenu = () => { + const dispatchAction = (action) => dispatchMenuAction(action); + const handleCopyAction = () => { + BrowserWindow.getFocusedWindow()?.webContents.copy(); + dispatchAction('copy'); + }; + + return Menu.buildFromTemplate([ + { + label: app.name, + submenu: [ + { role: 'about' }, + { + label: 'Check for Updates', + click: () => dispatchCheckForUpdates(), + }, + { type: 'separator' }, + { label: 'Settings', accelerator: 'Cmd+,', click: () => dispatchAction('settings') }, + { label: 'Command Palette', accelerator: 'Cmd+K', click: () => dispatchAction('command-palette') }, + { label: 'Quick Open…', accelerator: 'Cmd+P', click: () => dispatchAction('quick-open') }, + { type: 'separator' }, + { role: 'services' }, + { type: 'separator' }, + { role: 'hide' }, + { role: 'hideOthers' }, + { type: 'separator' }, + { role: 'quit' }, + ], + }, + { + label: 'File', + submenu: [ + { label: 'New Window', accelerator: 'Cmd+Shift+Alt+N', click: () => void handleInvoke(null, 'desktop_new_window') }, + { type: 'separator' }, + { label: 'New Session', accelerator: 'Cmd+N', click: () => dispatchAction('new-session') }, + { label: 'New Worktree', accelerator: 'Cmd+Shift+N', click: () => dispatchAction('new-worktree-session') }, + { type: 'separator' }, + { label: 'Add Workspace', click: () => dispatchAction('change-workspace') }, + { type: 'separator' }, + { role: 'close' }, + ], + }, + { + label: 'Edit', + submenu: [ + { role: 'undo' }, + { role: 'redo' }, + { type: 'separator' }, + { role: 'cut' }, + { label: 'Copy', accelerator: 'Cmd+C', click: () => handleCopyAction() }, + { role: 'paste' }, + { role: 'selectAll' }, + ], + }, + { + label: 'View', + submenu: [ + { label: 'Git', accelerator: 'Cmd+G', click: () => dispatchAction('open-git-tab') }, + { label: 'Diff', accelerator: 'Cmd+E', click: () => dispatchAction('open-diff-tab') }, + { label: 'Files', click: () => dispatchAction('open-files-tab') }, + { label: 'Terminal', accelerator: 'Cmd+T', click: () => dispatchAction('open-terminal-tab') }, + { type: 'separator' }, + { label: 'Light Theme', click: () => dispatchAction('theme-light') }, + { label: 'Dark Theme', click: () => dispatchAction('theme-dark') }, + { label: 'System Theme', click: () => dispatchAction('theme-system') }, + { type: 'separator' }, + { label: 'Toggle Session Sidebar', accelerator: 'Cmd+L', click: () => dispatchAction('toggle-sidebar') }, + { label: 'Toggle Memory Debug', accelerator: 'Cmd+Shift+D', click: () => dispatchAction('toggle-memory-debug') }, + { type: 'separator' }, + { role: 'togglefullscreen' }, + ], + }, + { + label: 'Window', + submenu: [ + { role: 'minimize' }, + { role: 'zoom' }, + { type: 'separator' }, + { role: 'close' }, + ], + }, + { + label: 'Help', + submenu: [ + { label: 'Keyboard Shortcuts', accelerator: 'Cmd+.', click: () => dispatchAction('help-dialog') }, + { label: 'Show Diagnostics', accelerator: 'Cmd+Shift+L', click: () => dispatchAction('download-logs') }, + { type: 'separator' }, + { label: 'Clear Cache', click: () => void handleInvoke(null, 'desktop_clear_cache') }, + { type: 'separator' }, + { label: 'Report a Bug', click: () => shell.openExternal(GITHUB_BUG_REPORT_URL) }, + { label: 'Request a Feature', click: () => shell.openExternal(GITHUB_FEATURE_REQUEST_URL) }, + { type: 'separator' }, + { label: 'Join Discord', click: () => shell.openExternal(DISCORD_INVITE_URL) }, + ], + }, + ]); +}; + +contextMenu({ + showInspectElement: isDev, + showSaveImageAs: true, + showCopyImage: true, + showCopyLink: true, +}); + +// All desktop_* IPC and dialog:open run with full Electron main privileges +// (fs access, shell.openPath, spawn, app.relaunch, …). The preload shim is +// injected into every webContents in the window, including remote hosts the +// user switches to via DesktopHostSwitcher. Without a gate, a malicious +// remote page could read arbitrary local files, open arbitrary apps, etc. +// +// Strategy: commands fall into two buckets by capability, not by origin. +// Window/host-switcher operations (probe a URL, open a new window, set +// title, read the hosts list) are safe for any renderer. Filesystem, +// shell.openPath, installed-app scans, app relaunch, and file dialogs +// are gated to local senders — even the user's own remote UI shouldn't +// need them, and a compromised remote can't use them either. +const isLocalSender = (webContents) => { + try { + const raw = typeof webContents?.getURL === 'function' ? webContents.getURL() : ''; + if (!raw) return false; + if (raw.startsWith('file://') || raw === 'about:blank') return true; + const url = new URL(raw); + if (url.protocol !== 'http:' && url.protocol !== 'https:') return false; + const hostname = url.hostname; + if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1') return true; + if (state.localOrigin) { + try { + const allowed = new URL(state.localOrigin); + if (allowed.origin === url.origin) return true; + } catch { + } + } + return false; + } catch { + return false; + } +}; + +const COMMANDS_SAFE_FOR_REMOTE = new Set([ + 'desktop_hosts_get', + 'desktop_host_probe', + 'desktop_new_window', + 'desktop_new_window_at_url', + 'desktop_set_window_title', + 'desktop_set_window_theme', + 'desktop_is_window_fullscreen', + 'desktop_start_window_drag', + 'desktop_get_app_version', + 'desktop_get_lan_address', +]); + +ipcMain.handle('openchamber:invoke', async (event, command, args) => { + if (!isLocalSender(event.sender) && !COMMANDS_SAFE_FOR_REMOTE.has(command)) { + log.warn(`[ipc] rejected ${command} from non-local origin: ${event.sender?.getURL?.() || '(unknown)'}`); + throw new Error('IPC not available for this origin'); + } + const browserWindow = BrowserWindow.fromWebContents(event.sender); + return handleInvoke(browserWindow, command, args); +}); + +ipcMain.handle('openchamber:dialog:open', async (event, options) => { + // Native file dialogs expose absolute local paths; never grant to remote. + if (!isLocalSender(event.sender)) { + log.warn(`[ipc] rejected dialog:open from non-local origin: ${event.sender?.getURL?.() || '(unknown)'}`); + throw new Error('IPC not available for this origin'); + } + const browserWindow = BrowserWindow.fromWebContents(event.sender); + const result = await dialog.showOpenDialog(browserWindow || undefined, { + title: typeof options?.title === 'string' ? options.title : undefined, + filters: Array.isArray(options?.filters) + ? options.filters + .filter((filter) => filter && typeof filter === 'object') + .map((filter) => ({ + name: typeof filter.name === 'string' && filter.name.trim().length > 0 ? filter.name : 'Files', + extensions: Array.isArray(filter.extensions) + ? filter.extensions.filter((extension) => typeof extension === 'string' && extension.trim().length > 0) + : [], + })) + : undefined, + properties: [ + options?.directory ? 'openDirectory' : 'openFile', + options?.multiple ? 'multiSelections' : null, + 'createDirectory', + ].filter(Boolean), + }); + if (result.canceled) return null; + if (options?.multiple) return result.filePaths; + return result.filePaths[0] || null; +}); + +app.on('window-all-closed', () => { + if (process.platform === 'darwin' && !state.quitRequested) { + return; + } + + killSidecar(); + void sshManager.shutdownAll(); + if (process.platform !== 'darwin') { + app.quit(); + } +}); + +app.on('before-quit', (event) => { + if (state.quitConfirmed || process.platform !== 'darwin') { + state.quitRequested = true; + return; + } + event.preventDefault(); + void requestQuitWithConfirmation(); +}); + +app.on('second-instance', (_event, argv) => { + const urls = Array.isArray(argv) + ? argv.filter((arg) => typeof arg === 'string' && arg.startsWith(`${DEEP_LINK_PROTOCOL}://`)) + : []; + if (urls.length > 0) handleDeepLinks(urls); + focusForegroundWindow(); +}); + +app.on('open-url', (event, url) => { + event.preventDefault(); + handleDeepLinks([url]); +}); + +app.on('activate', async () => { + const windows = BrowserWindow.getAllWindows().filter((window) => !window.isDestroyed()); + if (windows.length > 0) { + const visibleWindow = windows.find((window) => window.isVisible()); + const targetWindow = visibleWindow || state.mainWindow || windows[0]; + if (!targetWindow.isVisible()) { + targetWindow.show(); + } + targetWindow.focus(); + return; + } + + if (state.localOrigin) { + const config = readDesktopHostsConfig(); + const localUiUrl = state.sidecarUrl || state.localOrigin; + const host = config.defaultHostId && config.defaultHostId !== LOCAL_HOST_ID + ? config.hosts.find((entry) => entry.id === config.defaultHostId) + : null; + const targetUrl = host?.url && !state.unreachableHosts.has(host.url) ? host.url : localUiUrl; + await createAdditionalWindow(targetUrl); + } +}); + +app.whenReady().then(async () => { + log.info('[electron] app starting', { + version: APP_VERSION, + packaged: app.isPackaged, + platform: process.platform, + arch: process.arch, + }); + nativeTheme.themeSource = readThemeSource(); + setupAutoUpdater(); + + if (process.platform === 'darwin') { + Menu.setApplicationMenu(buildMacMenu()); + } + + const initial = extractInitialDeepLinks(); + if (initial.length > 0) handleDeepLinks(initial); + + const { initialUrl, localOrigin, bootOutcome } = await resolveInitialUrl(); + await activateMainWindow(initialUrl, localOrigin, bootOutcome); + startQuitRiskPoller(); +}).catch((error) => { + log.error('[electron] startup failed:', error); + app.exit(1); +}); diff --git a/packages/electron/package.json b/packages/electron/package.json new file mode 100644 index 00000000..80d0318b --- /dev/null +++ b/packages/electron/package.json @@ -0,0 +1,89 @@ +{ + "name": "@openchamber/electron", + "version": "1.9.6", + "private": true, + "description": "Electron desktop runtime for OpenChamber", + "author": "OpenChamber", + "type": "module", + "main": "./dist-bundle/main.mjs", + "dependencies": { + "@openchamber/web": "workspace:*", + "electron-context-menu": "^4.1.2", + "electron-log": "^5.4.3", + "electron-updater": "^6.8.3" + }, + "devDependencies": { + "@electron/rebuild": "^3.7.0", + "electron": "^41.2.1", + "electron-builder": "^26.0.0" + }, + "desktopPrerequisites": [ + "Electron runtime dependencies installed via bun install", + "Bun available for sidecar compilation", + "macOS build tools installed for notarized packaging" + ], + "scripts": { + "dev": "node ./scripts/electron-dev.mjs", + "build:web-assets": "node ./scripts/build-web-assets.mjs", + "build": "bun -e \"process.exit(0)\"", + "bundle:main": "bun ./scripts/bundle-main.mjs", + "rebuild:native": "node ./scripts/rebuild-native.mjs", + "package": "bun run build:web-assets && bun run bundle:main && bun run rebuild:native && electron-builder", + "finalize:latest-yml": "node ./scripts/finalize-latest-yml.mjs", + "type-check": "node --check ./main.mjs && node --check ./preload.mjs", + "lint": "node -e \"process.exit(0)\"" + }, + "build": { + "appId": "dev.openchamber.desktop", + "productName": "OpenChamber", + "files": [ + "dist-bundle/main.mjs", + "preload.mjs" + ], + "extraResources": [ + { + "from": "resources/web-dist", + "to": "web-dist" + } + ], + "directories": { + "buildResources": "resources/icons", + "output": "dist" + }, + "artifactName": "${productName}-${version}-${arch}.${ext}", + "npmRebuild": false, + "mac": { + "category": "public.app-category.developer-tools", + "icon": "resources/icons/icon.icns", + "hardenedRuntime": true, + "gatekeeperAssess": false, + "entitlements": "resources/entitlements.mac.plist", + "entitlementsInherit": "resources/entitlements.mac.plist", + "notarize": true, + "target": [ + "dmg", + "zip" + ] + }, + "dmg": { + "sign": true, + "title": "${productName} ${version}", + "backgroundColor": "#FFFCF0", + "iconSize": 100, + "iconTextSize": 13, + "window": { + "width": 540, + "height": 340 + }, + "contents": [ + { "x": 180, "y": 140, "type": "file" }, + { "x": 360, "y": 140, "type": "link", "path": "/Applications" } + ] + }, + "publish": { + "provider": "github", + "owner": "btriapitsyn", + "repo": "openchamber" + } + } +} diff --git a/packages/electron/preload.mjs b/packages/electron/preload.mjs new file mode 100644 index 00000000..3259ec5f --- /dev/null +++ b/packages/electron/preload.mjs @@ -0,0 +1,143 @@ +import { contextBridge, ipcRenderer } from 'electron'; + +const eventListeners = new Map(); + +const readArgValue = (name) => { + const prefix = `${name}=`; + const entry = process.argv.find((value) => typeof value === 'string' && value.startsWith(prefix)); + if (!entry) { + return ''; + } + return entry.slice(prefix.length); +}; + +const localOrigin = readArgValue('--openchamber-local-origin'); +const homeDirectory = readArgValue('--openchamber-home'); +const macosMajorRaw = readArgValue('--openchamber-macos-major'); +const macosMajor = Number.parseInt(macosMajorRaw, 10); + +// Preload re-executes on every cross-origin navigation (we run with +// sandbox:false, per-document). Two separate concerns to balance: +// - __OPENCHAMBER_ELECTRON__ is a shell-identity flag (no capability). +// Remote UIs still need it so isDesktopShell() returns true and the +// window renders with desktop affordances (DesktopHostSwitcher, +// title bar offsets, etc.). Expose unconditionally. +// - __TAURI__ is the IPC channel to the main process. Remote pages must +// not get it — otherwise any page loaded via DesktopHostSwitcher could +// read local files, open apps, relaunch, etc. Expose only on local +// pages (loopback / state.localOrigin / file:// for dev). +// Everything driven by localOrigin (home dir, macOS hints) also stays +// local-only since it leaks info about the Electron host machine. +const currentOrigin = (() => { + try { + return typeof location !== 'undefined' ? location.origin : ''; + } catch { + return ''; + } +})(); +const isLoopbackOrigin = /^https?:\/\/(localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/i.test(currentOrigin); +const isLocalPage = currentOrigin === 'null' + || isLoopbackOrigin + || (localOrigin && currentOrigin === localOrigin); + +// Remote pages need __OPENCHAMBER_LOCAL_ORIGIN__ so the HostSwitcher knows +// the URL of the Local entry (isDesktopLocalOriginActive() falls back to +// window.location.origin otherwise — wrong on remote). Low risk: the value +// is just "http://127.0.0.1:" which is not exploitable without the +// IPC channel, and CORS on the local server prevents remote-origin fetches. +if (localOrigin) { + contextBridge.exposeInMainWorld('__OPENCHAMBER_LOCAL_ORIGIN__', localOrigin); +} + +// Home directory leaks the OS username — keep local-only. Remote pages +// operate on the REMOTE server's filesystem, local home is irrelevant +// (and would be misleading if consumed as a workspace hint). +if (isLocalPage && homeDirectory) { + contextBridge.exposeInMainWorld('__OPENCHAMBER_HOME__', homeDirectory); +} + +// macOS major version drives window chrome offsets (traffic lights) — UI +// presentation only, safe to expose. +if (Number.isFinite(macosMajor) && macosMajor > 0) { + contextBridge.exposeInMainWorld('__OPENCHAMBER_MACOS_MAJOR__', macosMajor); +} + +contextBridge.exposeInMainWorld('__OPENCHAMBER_ELECTRON__', { + runtime: 'electron', +}); + +// Note: bootOutcome must stay writable from the main world's initScript so +// re-navigations (host switch via deep link) can refresh it. contextBridge- +// exposed globals are read-only, which blocks that update — rely solely on +// the main-process initScript injection (dispatched on did-finish-load). + +const addListener = (event, handler) => { + const listeners = eventListeners.get(event) || new Set(); + listeners.add(handler); + eventListeners.set(event, listeners); + + return () => { + const current = eventListeners.get(event); + if (!current) { + return; + } + current.delete(handler); + if (current.size === 0) { + eventListeners.delete(event); + } + }; +}; + +const dispatchNativeEvent = (event, detail) => { + const listeners = eventListeners.get(event); + if (listeners) { + for (const listener of listeners) { + try { + listener({ payload: detail }); + } catch (error) { + console.error(`[electron:preload] listener failed for ${event}:`, error); + } + } + } + + try { + const domEvent = detail === undefined + ? new Event(event) + : new CustomEvent(event, { detail }); + window.dispatchEvent(domEvent); + } catch (error) { + console.error(`[electron:preload] failed to dispatch DOM event ${event}:`, error); + } +}; + +// Main-process events are read-only notifications (update progress, +// window focus, etc.) — safe to deliver to any page rendered in this +// webContents. The events themselves don't grant capability. +ipcRenderer.on('openchamber:emit', (_evt, payload) => { + if (!payload || typeof payload !== 'object') { + return; + } + + const event = typeof payload.event === 'string' ? payload.event : ''; + if (!event) { + return; + } + + dispatchNativeEvent(event, payload.detail); +}); + +// __TAURI__ is exposed on all pages; the main-process gate in +// ipcMain.handle('openchamber:invoke') decides per-command what is safe +// for non-local callers (window/host-switcher ops yes, file/shell ops +// no). See COMMANDS_SAFE_FOR_REMOTE in main.mjs. +contextBridge.exposeInMainWorld('__TAURI__', { + core: { + invoke: (cmd, args) => ipcRenderer.invoke('openchamber:invoke', cmd, args || {}), + }, + dialog: { + open: (options) => ipcRenderer.invoke('openchamber:dialog:open', options || {}), + }, + event: { + listen: async (event, handler) => addListener(event, handler), + }, +}); diff --git a/packages/electron/resources/entitlements.mac.plist b/packages/electron/resources/entitlements.mac.plist new file mode 100644 index 00000000..03649c44 --- /dev/null +++ b/packages/electron/resources/entitlements.mac.plist @@ -0,0 +1,35 @@ + + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-executable-page-protection + + com.apple.security.cs.disable-library-validation + + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.device.audio-input + + com.apple.security.network.client + + com.apple.security.network.server + + com.apple.security.files.user-selected.read-write + + com.apple.security.inherit + + + diff --git a/packages/electron/resources/icons/app-icon.png b/packages/electron/resources/icons/app-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c3f9a038f17fe5305f67038915c7b236f002eea4 GIT binary patch literal 24006 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 literal 0 HcmV?d00001 diff --git a/packages/electron/resources/icons/app-icon.svg b/packages/electron/resources/icons/app-icon.svg new file mode 100644 index 00000000..f271cda8 --- /dev/null +++ b/packages/electron/resources/icons/app-icon.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/electron/resources/icons/dev-icon.icns b/packages/electron/resources/icons/dev-icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..04ac8d54096e7a3d66a5d9ffec0d34e7399ace29 GIT binary patch literal 173094 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 literal 0 HcmV?d00001 diff --git a/packages/electron/resources/icons/dev-icon.png b/packages/electron/resources/icons/dev-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bab0ca21ca11b65f91c81829863ba035857cb782 GIT binary patch literal 66751 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 ?)ZU+`JF{HUMVq3#D6a;` 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 z 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 literal 0 HcmV?d00001 diff --git a/packages/electron/resources/icons/icon.icns b/packages/electron/resources/icons/icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..b6def08054d43652c4d469fcfa6de7ae9fb6b02e GIT binary patch literal 160844 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 literal 0 HcmV?d00001 diff --git a/packages/electron/resources/icons/icon.png b/packages/electron/resources/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b9c1331d951b7825160d3683605a45308cfb9e6b GIT binary patch literal 55246 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

  • Wad7s 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�Eb8EGH+ZFiC4wILwDbzGc_0 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 literal 0 HcmV?d00001 diff --git a/packages/electron/scripts/build-web-assets.mjs b/packages/electron/scripts/build-web-assets.mjs new file mode 100644 index 00000000..9cca3521 --- /dev/null +++ b/packages/electron/scripts/build-web-assets.mjs @@ -0,0 +1,75 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { spawnSync } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const repoRoot = path.resolve(__dirname, '..', '..', '..'); +const webDir = path.join(repoRoot, 'packages', 'web'); +const electronDir = path.join(repoRoot, 'packages', 'electron'); + +const resourcesDir = path.join(electronDir, 'resources'); +const resourcesWebDistDir = path.join(resourcesDir, 'web-dist'); +const webDistDir = path.join(webDir, 'dist'); + +const run = (cmd, args, cwd) => { + const result = spawnSync(cmd, args, { cwd, stdio: 'inherit' }); + if (result.error) throw result.error; + if (result.status !== 0) { + throw new Error(`Command failed: ${cmd} ${args.join(' ')}`); + } +}; + +const resolveBun = () => { + if (typeof process.env.BUN === 'string' && process.env.BUN.trim()) { + return process.env.BUN.trim(); + } + const result = spawnSync('/bin/bash', ['-lc', 'command -v bun'], { encoding: 'utf8' }); + const resolved = (result.stdout || '').trim(); + return resolved || 'bun'; +}; + +const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + +const removeDir = async (target) => { + for (let attempt = 0; attempt < 5; attempt += 1) { + try { + await fs.rm(target, { recursive: true, force: true }); + return; + } catch (error) { + if (attempt === 4) throw error; + if (!['ENOTEMPTY', 'EBUSY', 'EPERM'].includes(error?.code)) throw error; + await sleep(100 * (attempt + 1)); + } + } +}; + +const copyDir = async (src, dst) => { + await fs.mkdir(dst, { recursive: true }); + const entries = await fs.readdir(src, { withFileTypes: true }); + for (const entry of entries) { + const from = path.join(src, entry.name); + const to = path.join(dst, entry.name); + if (entry.isDirectory()) { + await copyDir(from, to); + } else { + await fs.copyFile(from, to); + } + } +}; + +const bunExe = resolveBun(); + +console.log('[electron] building web UI dist...'); +run(bunExe, ['run', 'build'], webDir); + +console.log('[electron] staging packaged resources...'); +await fs.mkdir(resourcesDir, { recursive: true }); +const stagedWebDistDir = await fs.mkdtemp(path.join(resourcesDir, 'web-dist-staging-')); +await copyDir(webDistDir, stagedWebDistDir); +await removeDir(resourcesWebDistDir); +await fs.rename(stagedWebDistDir, resourcesWebDistDir); + +console.log(`[electron] web assets ready: ${resourcesWebDistDir}`); diff --git a/packages/electron/scripts/bundle-main.mjs b/packages/electron/scripts/bundle-main.mjs new file mode 100644 index 00000000..e8d06d36 --- /dev/null +++ b/packages/electron/scripts/bundle-main.mjs @@ -0,0 +1,44 @@ +/** + * Bundle main.mjs into a single file. Small electron-* helper deps are + * inlined; everything else — including the in-process web server + * (@openchamber/web) and native modules — stays external so it resolves + * from node_modules at runtime inside the packaged app. + * + * Why external matters: packages/web/server pulls in bun-pty, which has + * a top-level `import { dlopen } from "bun:ffi"`. If we inline it here, + * Node's ESM loader sees `bun:ffi` at package load time and crashes with + * ERR_UNSUPPORTED_ESM_URL_SCHEME before any runtime guard can skip it. + * Leaving @openchamber/web external means the conditional + * `if (isBunRuntime) await import('bun-pty')` stays dynamic and is never + * reached under Electron. + */ +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const root = path.resolve(__dirname, '..'); + +const result = await Bun.build({ + entrypoints: [path.join(root, 'main.mjs')], + outdir: path.join(root, 'dist-bundle'), + target: 'node', + format: 'esm', + external: [ + 'electron', + '@openchamber/web', + '@openchamber/web/*', + 'bun-pty', + 'node-pty', + 'better-sqlite3', + ], + minify: false, + sourcemap: 'none', + naming: '[name].mjs', +}); + +if (!result.success) { + for (const msg of result.logs) console.error(msg); + process.exit(1); +} + +console.log('[electron] main.mjs bundled -> dist-bundle/main.mjs'); diff --git a/packages/electron/scripts/electron-dev.mjs b/packages/electron/scripts/electron-dev.mjs new file mode 100644 index 00000000..46c2ce43 --- /dev/null +++ b/packages/electron/scripts/electron-dev.mjs @@ -0,0 +1,131 @@ +#!/usr/bin/env node +import { spawn } from 'node:child_process'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const repoRoot = path.resolve(__dirname, '../../..'); +const electronDir = path.join(repoRoot, 'packages/electron'); + +function spawnProcess(command, args, options = {}) { + return spawn(command, args, { + cwd: repoRoot, + env: { ...process.env, OPENCHAMBER_ELECTRON_DEV: '1' }, + stdio: 'inherit', + detached: process.platform !== 'win32', + ...options, + }); +} + +function waitForExit(child, timeoutMs) { + return new Promise((resolve) => { + if (!child || child.exitCode !== null || child.signalCode !== null) { + resolve(); + return; + } + + const onExit = () => { + clearTimeout(timer); + resolve(); + }; + + const timer = setTimeout(() => { + child.off('exit', onExit); + resolve(); + }, timeoutMs); + + child.once('exit', onExit); + }); +} + +function signalChild(child, signal) { + if (!child || child.exitCode !== null || child.signalCode !== null) { + return; + } + + try { + if (process.platform !== 'win32') { + process.kill(-child.pid, signal); + return; + } + } catch { + } + + try { + child.kill(signal); + } catch { + } +} + +async function stopChildTree(child) { + if (!child || child.exitCode !== null || child.signalCode !== null) { + return; + } + + signalChild(child, 'SIGINT'); + await waitForExit(child, 2500); + + if (child.exitCode === null && child.signalCode === null) { + signalChild(child, 'SIGTERM'); + await waitForExit(child, 2500); + } + + if (child.exitCode === null && child.signalCode === null) { + signalChild(child, 'SIGKILL'); + await waitForExit(child, 1000); + } +} + +async function main() { + const devServer = spawnProcess('node', ['./scripts/dev-web-hmr.mjs'], { + env: { + ...process.env, + OPENCHAMBER_ELECTRON_DEV: '1', + OPENCHAMBER_HMR_UI_PORT: '5173', + OPENCHAMBER_HMR_API_PORT: '3901', + OPENCHAMBER_DISABLE_PWA_DEV: '1', + }, + }); + const electron = spawnProcess('npx', ['electron', './main.mjs'], { cwd: electronDir }); + + let cleaning = false; + const teardown = async (code) => { + if (cleaning) { + return; + } + cleaning = true; + + await Promise.all([stopChildTree(electron), stopChildTree(devServer)]); + process.exit(typeof code === 'number' ? code : 0); + }; + + const onChildExit = (label) => (code, signal) => { + if (code !== 0 || signal) { + console.warn(`[electron:dev] ${label} exited with code ${code ?? 'null'} signal ${signal ?? 'none'}.`); + } + void teardown(code ?? 1); + }; + + devServer.on('exit', onChildExit('dev server')); + electron.on('exit', onChildExit('electron')); + devServer.on('error', (error) => { + console.error('[electron:dev] failed to start dev server:', error); + void teardown(1); + }); + electron.on('error', (error) => { + console.error('[electron:dev] failed to start electron:', error); + void teardown(1); + }); + + for (const [signal, exitCode] of Object.entries({ SIGINT: 130, SIGTERM: 143, SIGQUIT: 131, SIGHUP: 129 })) { + process.on(signal, () => { + void teardown(exitCode); + }); + } +} + +main().catch((error) => { + console.error('[electron:dev] unexpected error:', error); + process.exit(1); +}); diff --git a/packages/electron/scripts/finalize-latest-yml.mjs b/packages/electron/scripts/finalize-latest-yml.mjs new file mode 100644 index 00000000..68b2de18 --- /dev/null +++ b/packages/electron/scripts/finalize-latest-yml.mjs @@ -0,0 +1,113 @@ +#!/usr/bin/env node +import fs from 'node:fs/promises'; +import path from 'node:path'; + +const dir = process.env.LATEST_YML_DIR; +const repo = process.env.GH_REPO; +const version = process.env.OPENCHAMBER_VERSION; + +if (!dir) throw new Error('LATEST_YML_DIR is required'); +if (!repo) throw new Error('GH_REPO is required'); +if (!version) throw new Error('OPENCHAMBER_VERSION is required'); + +const parse = (content) => { + const lines = content.split('\n'); + let releaseDate = ''; + let parsedVersion = ''; + const files = []; + let current; + + const flush = () => { + if (current?.url && current?.sha512 && current?.size) { + files.push(current); + } + current = undefined; + }; + + for (const line of lines) { + const trimmed = line.trim(); + const indented = line.startsWith(' ') || line.startsWith(' -'); + if (line.startsWith('version:')) { + parsedVersion = line.slice('version:'.length).trim(); + } else if (line.startsWith('releaseDate:')) { + releaseDate = line.slice('releaseDate:'.length).trim().replace(/^'|'$/g, ''); + } else if (trimmed.startsWith('- url:')) { + flush(); + current = { url: trimmed.slice('- url:'.length).trim() }; + } else if (indented && current && trimmed.startsWith('sha512:')) { + current.sha512 = trimmed.slice('sha512:'.length).trim(); + } else if (indented && current && trimmed.startsWith('size:')) { + current.size = Number(trimmed.slice('size:'.length).trim()); + } else if (indented && current && trimmed.startsWith('blockMapSize:')) { + current.blockMapSize = Number(trimmed.slice('blockMapSize:'.length).trim()); + } else if (!indented && current) { + flush(); + } + } + + flush(); + return { version: parsedVersion, releaseDate, files }; +}; + +const serialize = (data) => { + const lines = [`version: ${data.version}`, 'files:']; + for (const file of data.files) { + lines.push(` - url: ${file.url}`); + lines.push(` sha512: ${file.sha512}`); + lines.push(` size: ${file.size}`); + if (file.blockMapSize) { + lines.push(` blockMapSize: ${file.blockMapSize}`); + } + } + lines.push(`releaseDate: '${data.releaseDate}'`); + return `${lines.join('\n')}\n`; +}; + +const read = async (subdir, filename) => { + const filePath = path.join(dir, subdir, filename); + try { + return parse(await fs.readFile(filePath, 'utf8')); + } catch { + return null; + } +}; + +const output = {}; + +const winX64 = await read('latest-yml-x86_64-pc-windows-msvc', 'latest.yml'); +const winArm64 = await read('latest-yml-aarch64-pc-windows-msvc', 'latest.yml'); +if (winX64 || winArm64) { + const base = winArm64 || winX64; + output['latest.yml'] = serialize({ + version: base.version, + files: [...(winArm64?.files || []), ...(winX64?.files || [])], + releaseDate: base.releaseDate, + }); +} + +const linuxX64 = await read('latest-yml-x86_64-unknown-linux-gnu', 'latest-linux.yml'); +if (linuxX64) output['latest-linux.yml'] = serialize(linuxX64); + +const linuxArm64 = await read('latest-yml-aarch64-unknown-linux-gnu', 'latest-linux-arm64.yml'); +if (linuxArm64) output['latest-linux-arm64.yml'] = serialize(linuxArm64); + +const macX64 = await read('latest-yml-x86_64-apple-darwin', 'latest-mac.yml'); +const macArm64 = await read('latest-yml-aarch64-apple-darwin', 'latest-mac.yml'); +if (macX64 || macArm64) { + const base = macArm64 || macX64; + output['latest-mac.yml'] = serialize({ + version: base.version, + files: [...(macArm64?.files || []), ...(macX64?.files || [])], + releaseDate: base.releaseDate, + }); +} + +const tag = `v${version}`; +const tmp = process.env.RUNNER_TEMP || '/tmp'; +for (const [filename, content] of Object.entries(output)) { + const outputPath = path.join(tmp, filename); + await fs.writeFile(outputPath, content); + console.log(`prepared ${outputPath} for upload to ${repo} release ${tag}`); +} + +console.log('finalized latest yml files'); diff --git a/packages/electron/scripts/rebuild-native.mjs b/packages/electron/scripts/rebuild-native.mjs new file mode 100644 index 00000000..eb381df7 --- /dev/null +++ b/packages/electron/scripts/rebuild-native.mjs @@ -0,0 +1,30 @@ +#!/usr/bin/env node +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { createRequire } from 'node:module'; +import { rebuild } from '@electron/rebuild'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const electronDir = path.resolve(__dirname, '..'); +const repoRoot = path.resolve(electronDir, '..', '..'); +const require = createRequire(import.meta.url); + +const electronPkg = require('electron/package.json'); +const electronVersion = electronPkg.version; + +console.log(`[electron] rebuilding native modules against Electron ${electronVersion}...`); + +// Rebuild against the hoisted root node_modules (bun workspace layout). +// force=true re-links regardless of cached state; prebuild-install lookup is +// bypassed by @electron/rebuild in favor of direct node-gyp builds. +await rebuild({ + buildPath: repoRoot, + electronVersion, + force: true, + arch: process.env.ELECTRON_BUILDER_ARCH || process.arch, + onlyModules: ['better-sqlite3', 'node-pty', 'bun-pty'], +}); + +console.log('[electron] native modules rebuilt successfully'); diff --git a/packages/electron/ssh-manager.mjs b/packages/electron/ssh-manager.mjs new file mode 100644 index 00000000..ed64093b --- /dev/null +++ b/packages/electron/ssh-manager.mjs @@ -0,0 +1,1240 @@ +import fs from 'node:fs'; +import fsp from 'node:fs/promises'; +import net from 'node:net'; +import os from 'node:os'; +import path from 'node:path'; +import { spawn } from 'node:child_process'; + +const LOCAL_HOST_ID = 'local'; +const DEFAULT_CONNECTION_TIMEOUT_SEC = 60; +const DEFAULT_LOCAL_BIND_HOST = '127.0.0.1'; +const DEFAULT_CONTROL_PERSIST_SEC = 300; +const DEFAULT_READY_TIMEOUT_SEC = 30; +const DEFAULT_RECONNECT_MAX_ATTEMPTS = 5; +const MAX_LOG_LINES_PER_INSTANCE = 1200; + +const MONITOR_INITIAL_POLL_MS = 2000; +const MONITOR_STEADY_POLL_MS = 10000; +const MONITOR_STABILIZE_TICKS = 5; +const SSH_STATUS_EVENT = 'openchamber:ssh-instance-status'; + +const nowMillis = () => Date.now(); + +const shellQuote = (value) => `'${String(value).replace(/'/g, `'\\''`)}'`; + +const hasGlobWildcard = (value) => /[*?]/.test(value); + +const expandSshIncludeToken = (token, baseDir) => { + const trimmed = String(token || '').trim(); + if (!trimmed) return []; + + const expandedHome = trimmed.startsWith('~/') + ? path.join(os.homedir(), trimmed.slice(2)) + : (trimmed === '~' ? os.homedir() : trimmed); + const resolved = path.isAbsolute(expandedHome) + ? expandedHome + : path.resolve(baseDir, expandedHome); + + if (!hasGlobWildcard(resolved)) { + return fs.existsSync(resolved) ? [resolved] : []; + } + + const dir = path.dirname(resolved); + const namePattern = path.basename(resolved); + if (hasGlobWildcard(dir) || !fs.existsSync(dir)) { + return []; + } + + const matcher = new RegExp(`^${namePattern + .replace(/[.+^${}()|[\]\\]/g, '\\$&') + .replace(/\*/g, '.*') + .replace(/\?/g, '.')}$`); + + try { + return fs.readdirSync(dir) + .filter((name) => matcher.test(name)) + .map((name) => path.join(dir, name)) + .filter((candidate) => fs.existsSync(candidate)) + .sort((left, right) => left.localeCompare(right)); + } catch { + return []; + } +}; + +const readJsonRoot = (settingsFilePath) => { + try { + const parsed = JSON.parse(fs.readFileSync(settingsFilePath, 'utf8')); + return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {}; + } catch { + return {}; + } +}; + +const writeJsonRoot = async (settingsFilePath, root) => { + await fsp.mkdir(path.dirname(settingsFilePath), { recursive: true }); + await fsp.writeFile(settingsFilePath, JSON.stringify(root, null, 2)); +}; + +const defaultTrue = () => true; + +const sanitizeBindHost = (raw) => { + const trimmed = typeof raw === 'string' ? raw.trim() : ''; + if (!trimmed) return DEFAULT_LOCAL_BIND_HOST; + return ['127.0.0.1', 'localhost', '0.0.0.0'].includes(trimmed) ? trimmed : DEFAULT_LOCAL_BIND_HOST; +}; + +const splitShellWords = (input) => { + const tokens = []; + let current = ''; + let inSingle = false; + let inDouble = false; + const chars = [...String(input)]; + + for (let index = 0; index < chars.length; index += 1) { + const ch = chars[index]; + if (ch === '\\' && !inSingle) { + index += 1; + if (index < chars.length) current += chars[index]; + continue; + } + if (ch === '\'' && !inDouble) { + inSingle = !inSingle; + continue; + } + if (ch === '"' && !inSingle) { + inDouble = !inDouble; + continue; + } + if (/\s/.test(ch) && !inSingle && !inDouble) { + if (current) { + tokens.push(current); + current = ''; + } + continue; + } + current += ch; + } + + if (inSingle || inDouble) { + throw new Error('Unclosed quote in SSH command'); + } + if (current) tokens.push(current); + return tokens; +}; + +const isDisallowedPrimaryFlag = (token) => { + return ['-M', '-S', '-O', '-N', '-t', '-T', '-f', '-G', '-W', '-v', '-V', '-q', '-n', '-s', '-e', '-E', '-g'].includes(token); +}; + +const hasDisallowedOOption = (value) => { + const lower = String(value).trim().toLowerCase(); + return ['controlmaster', 'controlpath', 'controlpersist', 'batchmode', 'proxycommand'].some((prefix) => lower.startsWith(prefix)); +}; + +const parseSshCommand = (raw) => { + const tokens = splitShellWords(raw); + if (tokens.length === 0) { + throw new Error('SSH command is empty'); + } + + if (tokens[0] === 'ssh') { + tokens.shift(); + } + + if (tokens.length === 0) { + throw new Error('SSH command must include destination'); + } + + const allowedFlags = new Set(['-4', '-6', '-A', '-a', '-C', '-K', '-k', '-X', '-x', '-Y', '-y']); + const allowedWithValues = ['-B', '-b', '-c', '-D', '-F', '-I', '-i', '-J', '-l', '-m', '-o', '-P', '-p', '-R']; + + const args = []; + let destination = null; + for (let index = 0; index < tokens.length;) { + const token = tokens[index]; + if (destination) { + throw new Error(`SSH command has unsupported trailing argument: ${token}`); + } + + if (!token.startsWith('-')) { + destination = token.trim(); + index += 1; + continue; + } + + if (isDisallowedPrimaryFlag(token)) { + throw new Error(`SSH option ${token} is not allowed`); + } + + if (allowedFlags.has(token)) { + args.push(token); + index += 1; + continue; + } + + let matched = false; + for (const option of allowedWithValues) { + if (token === option) { + const value = tokens[index + 1]; + if (!value) { + throw new Error(`SSH option ${option} requires a value`); + } + if (option === '-o' && hasDisallowedOOption(value)) { + throw new Error(`SSH option -o ${value} is not allowed`); + } + args.push(token, value); + index += 2; + matched = true; + break; + } + + if (token.startsWith(option) && token.length > option.length) { + const value = token.slice(option.length); + if (option === '-o' && hasDisallowedOOption(value)) { + throw new Error(`SSH option -o ${value} is not allowed`); + } + args.push(token); + index += 1; + matched = true; + break; + } + } + + if (!matched) { + throw new Error(`Unsupported SSH option: ${token}`); + } + } + + if (!destination) { + throw new Error('SSH command must include destination'); + } + + return { destination, args }; +}; + +const runOutput = async (command, args, options = {}) => { + return await new Promise((resolve, reject) => { + const child = spawn(command, args, { + stdio: ['pipe', 'pipe', 'pipe'], + ...options, + }); + + let stdout = ''; + let stderr = ''; + child.stdout?.on('data', (chunk) => { + stdout += chunk.toString(); + }); + child.stderr?.on('data', (chunk) => { + stderr += chunk.toString(); + }); + child.on('error', reject); + child.on('close', (code) => { + resolve({ code: typeof code === 'number' ? code : -1, stdout, stderr }); + }); + }); +}; + +const buildSshArgs = (parsed, preDestinationArgs = [], remoteCommand = null) => { + const args = [...parsed.args, ...preDestinationArgs, parsed.destination]; + if (remoteCommand) args.push(remoteCommand); + return args; +}; + +const runRemoteCommand = async (parsed, controlPath, script, timeoutSec = DEFAULT_CONNECTION_TIMEOUT_SEC) => { + const args = buildSshArgs(parsed, [ + '-o', 'ControlMaster=no', + '-o', `ControlPath=${controlPath}`, + '-o', `ConnectTimeout=${timeoutSec}`, + '-T', + ], `sh -lc ${shellQuote(script)}`); + const { code, stdout, stderr } = await runOutput('ssh', args); + if (code !== 0) { + throw new Error((stderr || stdout || 'Remote command failed').trim()); + } + return stdout; +}; + +const controlMasterOperation = async (parsed, controlPath, op) => { + return await runOutput('ssh', buildSshArgs(parsed, [ + '-o', 'ControlMaster=no', + '-o', `ControlPath=${controlPath}`, + '-o', 'BatchMode=yes', + '-o', 'ConnectTimeout=3', + '-O', op, + ])); +}; + +const isControlMasterAlive = async (parsed, controlPath) => { + const { code } = await controlMasterOperation(parsed, controlPath, 'check'); + return code === 0; +}; + +const stopControlMasterBestEffort = async (parsed, controlPath) => { + try { + await controlMasterOperation(parsed, controlPath, 'exit'); + } catch { + } +}; + +const askpassScriptContent = () => `#!/bin/bash +PROMPT="$1" + +if [[ -n "$OPENCHAMBER_SSH_ASKPASS_VALUE" ]]; then + if [[ "$PROMPT" == *"assword"* || "$PROMPT" == *"passphrase"* ]]; then + printf '%s\\n' "$OPENCHAMBER_SSH_ASKPASS_VALUE" + exit 0 + fi +fi + +DEFAULT_ANSWER="" +HIDDEN_INPUT="true" + +if [[ "$PROMPT" == *"yes/no"* ]]; then + DEFAULT_ANSWER="yes" + HIDDEN_INPUT="false" +fi + +if command -v osascript >/dev/null 2>&1; then + /usr/bin/osascript <<'APPLESCRIPT' "$PROMPT" "$DEFAULT_ANSWER" "$HIDDEN_INPUT" +on run argv + set promptText to item 1 of argv + set defaultAnswer to item 2 of argv + set hiddenInput to item 3 of argv + + try + if hiddenInput is "true" then + set response to display dialog promptText default answer defaultAnswer with hidden answer buttons {"Cancel", "OK"} default button "OK" + else + set response to display dialog promptText default answer defaultAnswer buttons {"Cancel", "OK"} default button "OK" + end if + return text returned of response + on error + error number -128 + end try +end run +APPLESCRIPT + exit $? +fi + +printf '%s\\n' "$DEFAULT_ANSWER" +`; + +const writeAskpassScript = async (scriptPath) => { + await fsp.writeFile(scriptPath, askpassScriptContent(), { mode: 0o700 }); + await fsp.chmod(scriptPath, 0o700); +}; + +const randomPortCandidate = (seed) => { + let hash = 0; + const source = `${seed}:${Date.now()}`; + for (let index = 0; index < source.length; index += 1) { + hash = ((hash << 5) - hash + source.charCodeAt(index)) | 0; + } + const base = 20000; + const span = 30000; + return base + Math.abs(hash % span); +}; + +const pickUnusedLocalPort = async () => { + return await new Promise((resolve, reject) => { + const server = net.createServer(); + server.listen(0, '127.0.0.1', () => { + const address = server.address(); + const port = typeof address === 'object' && address ? address.port : 0; + server.close((error) => error ? reject(error) : resolve(port)); + }); + server.on('error', reject); + }); +}; + +const isLocalPortAvailable = async (bindHost, port) => { + return await new Promise((resolve) => { + const server = net.createServer(); + server.once('error', () => resolve(false)); + server.listen(port, bindHost, () => { + server.close(() => resolve(true)); + }); + }); +}; + +const isLocalTunnelReachable = async (localPort) => { + return await new Promise((resolve) => { + const socket = net.createConnection({ host: '127.0.0.1', port: localPort }); + const finish = (value) => { + socket.destroy(); + resolve(value); + }; + socket.once('connect', () => finish(true)); + socket.once('error', () => finish(false)); + socket.setTimeout(500, () => finish(false)); + }); +}; + +const waitLocalForwardReady = async (localPort) => { + const deadline = Date.now() + (DEFAULT_READY_TIMEOUT_SEC * 1000); + let pollMs = 250; + while (Date.now() < deadline) { + try { + const response = await fetch(`http://127.0.0.1:${localPort}/health`, { signal: AbortSignal.timeout(1000) }); + if (response.ok || response.status === 401) { + return; + } + } catch { + } + await new Promise((resolve) => setTimeout(resolve, pollMs)); + pollMs = Math.min(pollMs * 2, 2000); + } + throw new Error('Timed out waiting for forwarded OpenChamber health'); +}; + +const parseVersionToken = (raw) => { + for (const token of String(raw).split(/\s+/)) { + let candidate = token.trim().replace(/^v/, ''); + candidate = candidate.replace(/[,)]+$/g, ''); + const parts = candidate.split('.'); + if (parts.length >= 2 && parts.every((part) => /^\d+$/.test(part))) { + return candidate; + } + } + return null; +}; + +const parseProbeStatusLine = (line, prefix) => { + if (!line || !line.startsWith(prefix)) return null; + const value = Number.parseInt(line.slice(prefix.length).trim(), 10); + return Number.isFinite(value) ? value : null; +}; + +const isAuthHttpStatus = (status) => status === 401 || status === 403; +const isLivenessHttpStatus = (status) => (status >= 200 && status <= 299) || isAuthHttpStatus(status); + +export class ElectronSshManager { + constructor(options) { + this.settingsFilePath = options.settingsFilePath; + this.appVersion = options.appVersion; + this.emit = options.emit; + this.logs = new Map(); + this.statuses = new Map(); + this.sessions = new Map(); + this.monitorTimers = new Map(); + this.reconnectAttempts = new Map(); + this.connectAttempts = new Map(); + this.connecting = new Map(); + } + + appendLogWithLevel(id, level, message) { + const line = `[${nowMillis()}] [${level}] ${message}`; + const current = this.logs.get(id) || []; + current.push(line); + if (current.length > MAX_LOG_LINES_PER_INSTANCE) { + current.splice(0, current.length - MAX_LOG_LINES_PER_INSTANCE); + } + this.logs.set(id, current); + } + + appendLog(id, message) { + this.appendLogWithLevel(id, 'INFO', message); + } + + appendAttemptSeparator(id, connectAttempt, retryAttempt) { + const scope = retryAttempt > 0 ? `retry ${retryAttempt}` : 'manual'; + this.appendLogWithLevel(id, 'INFO', `---------------- attempt #${connectAttempt} (${scope}) ----------------`); + } + + statusSnapshotForInstance(id) { + return this.statuses.get(id) || { + id, + phase: 'idle', + detail: null, + localUrl: null, + localPort: null, + remotePort: null, + startedByUs: false, + retryAttempt: 0, + requiresUserAction: false, + updatedAtMs: nowMillis(), + }; + } + + setStatus(id, phase, detail = null, localUrl = null, localPort = null, remotePort = null, startedByUs = false, retryAttempt = 0, requiresUserAction = false) { + const level = phase === 'error' ? 'ERROR' : (phase === 'degraded' ? 'WARN' : 'INFO'); + this.appendLogWithLevel( + id, + level, + `phase=${JSON.stringify(phase)} detail=${detail || ''} retry=${retryAttempt} requires_user_action=${requiresUserAction}`, + ); + + const status = { + id, + phase, + detail, + localUrl, + localPort, + remotePort, + startedByUs, + retryAttempt, + requiresUserAction, + updatedAtMs: nowMillis(), + }; + this.statuses.set(id, status); + this.emit(SSH_STATUS_EVENT, status); + } + + clearRetryAttempt(id) { + this.reconnectAttempts.delete(id); + } + + nextRetryAttempt(id) { + const next = (this.reconnectAttempts.get(id) || 0) + 1; + this.reconnectAttempts.set(id, next); + return next; + } + + currentRetryAttempt(id) { + return this.reconnectAttempts.get(id) || 0; + } + + nextConnectAttempt(id) { + const next = (this.connectAttempts.get(id) || 0) + 1; + this.connectAttempts.set(id, next); + return next; + } + + logsForInstance(id, limit = 200) { + const lines = [...(this.logs.get(id) || [])]; + return limit > 0 && lines.length > limit ? lines.slice(-limit) : lines; + } + + clearLogsForInstance(id) { + this.logs.delete(id); + } + + parseSshConfigCandidates(filePath, source, visited = new Set()) { + const resolvedPath = path.resolve(filePath); + if (visited.has(resolvedPath) || !fs.existsSync(resolvedPath)) return []; + visited.add(resolvedPath); + + const content = fs.readFileSync(resolvedPath, 'utf8'); + const candidates = []; + const baseDir = path.dirname(resolvedPath); + for (const line of content.split(/\r?\n/)) { + const trimmed = (line.split('#')[0] || '').trim(); + if (!trimmed) continue; + + if (/^include(?:\s|$)/i.test(trimmed)) { + const includeExpr = trimmed.replace(/^include\s+/i, '').trim(); + if (!includeExpr) continue; + let includeTokens = []; + try { + includeTokens = splitShellWords(includeExpr); + } catch { + includeTokens = includeExpr.split(/\s+/).filter(Boolean); + } + for (const includeToken of includeTokens) { + const includePaths = expandSshIncludeToken(includeToken, baseDir); + for (const includePath of includePaths) { + candidates.push(...this.parseSshConfigCandidates(includePath, source, visited)); + } + } + continue; + } + + if (!/^host(?:\s|$)/i.test(trimmed)) continue; + const rest = trimmed.replace(/^host\s+/i, '').trim(); + if (!rest) continue; + for (const token of rest.split(/\s+/)) { + const host = token.trim(); + if (!host || host.startsWith('!') || host === '*') continue; + candidates.push({ + host, + pattern: /[*?]/.test(host), + source, + sshCommand: `ssh ${host}`, + }); + } + } + return candidates; + } + + async importHosts() { + const candidates = [ + ...this.parseSshConfigCandidates(path.join(os.homedir(), '.ssh', 'config'), 'user'), + ...this.parseSshConfigCandidates('/etc/ssh/ssh_config', 'global'), + ]; + const seen = new Set(); + return candidates + .filter((item) => !seen.has(item.host) && seen.add(item.host)) + .sort((left, right) => left.host.localeCompare(right.host)); + } + + readInstances() { + const root = readJsonRoot(this.settingsFilePath); + return { instances: Array.isArray(root.desktopSshInstances) ? root.desktopSshInstances : [] }; + } + + async setInstances(config) { + const root = readJsonRoot(this.settingsFilePath); + const instances = Array.isArray(config?.instances) ? config.instances.map((instance) => this.sanitizeInstance(instance)) : []; + root.desktopSshInstances = instances; + + const previousIds = new Set((Array.isArray(root.desktopHosts) ? root.desktopHosts : []).map((entry) => String(entry?.id || '').trim()).filter(Boolean)); + const hosts = Array.isArray(root.desktopHosts) ? root.desktopHosts.filter(Boolean) : []; + const nextIds = new Set(instances.map((instance) => instance.id)); + + const filteredHosts = hosts.filter((entry) => { + const id = String(entry?.id || '').trim(); + return id && !(previousIds.has(id) && !nextIds.has(id)); + }); + + for (const instance of instances) { + const label = instance.nickname?.trim() || instance.sshParsed?.destination || instance.id; + const existing = filteredHosts.find((entry) => entry?.id === instance.id); + if (existing) { + existing.label = label; + if (!existing.url || !String(existing.url).trim()) { + existing.url = 'http://127.0.0.1/'; + } + } else { + filteredHosts.push({ id: instance.id, label, url: 'http://127.0.0.1/' }); + } + } + + root.desktopHosts = filteredHosts; + if (typeof root.desktopDefaultHostId === 'string' && previousIds.has(root.desktopDefaultHostId) && !nextIds.has(root.desktopDefaultHostId)) { + root.desktopDefaultHostId = LOCAL_HOST_ID; + } + + await writeJsonRoot(this.settingsFilePath, root); + } + + sanitizeStoredSecret(secret) { + if (!secret || typeof secret !== 'object') return undefined; + return { + enabled: Boolean(secret.enabled), + store: secret.store === 'settings' ? 'settings' : 'never', + ...(typeof secret.value === 'string' && secret.value.trim() ? { value: secret.value } : {}), + }; + } + + sanitizeForward(forward) { + const id = typeof forward?.id === 'string' ? forward.id.trim() : ''; + if (!id) return null; + const type = forward?.type === 'remote' || forward?.type === 'dynamic' ? forward.type : 'local'; + const normalized = { + id, + enabled: forward?.enabled !== false, + type, + ...(forward?.localHost ? { localHost: sanitizeBindHost(forward.localHost) } : {}), + ...(Number.isFinite(forward?.localPort) ? { localPort: Number(forward.localPort) } : {}), + ...(forward?.remoteHost ? { remoteHost: String(forward.remoteHost).trim() || '127.0.0.1' } : {}), + ...(Number.isFinite(forward?.remotePort) ? { remotePort: Number(forward.remotePort) } : {}), + }; + + if (type === 'local' || type === 'remote') { + if (!normalized.localPort || !normalized.remotePort) return null; + normalized.remoteHost = normalized.remoteHost || '127.0.0.1'; + normalized.localHost = normalized.localHost || '127.0.0.1'; + } + if (type === 'dynamic' && !normalized.localPort) { + return null; + } + return normalized; + } + + sanitizeInstance(instance) { + const id = typeof instance?.id === 'string' ? instance.id.trim() : ''; + const sshCommand = typeof instance?.sshCommand === 'string' ? instance.sshCommand.trim() : ''; + if (!id || id === LOCAL_HOST_ID) { + throw new Error('SSH instance id is required'); + } + if (!sshCommand) { + throw new Error('SSH command is required'); + } + + const parsed = parseSshCommand(sshCommand); + const seen = new Set(); + const portForwards = Array.isArray(instance?.portForwards) + ? instance.portForwards + .map((forward) => this.sanitizeForward(forward)) + .filter((forward) => forward && !seen.has(forward.id) && seen.add(forward.id)) + : []; + + return { + id, + ...(typeof instance?.nickname === 'string' && instance.nickname.trim() ? { nickname: instance.nickname.trim() } : {}), + sshCommand, + sshParsed: parsed, + connectionTimeoutSec: Number.isFinite(instance?.connectionTimeoutSec) && Number(instance.connectionTimeoutSec) > 0 + ? Number(instance.connectionTimeoutSec) + : DEFAULT_CONNECTION_TIMEOUT_SEC, + remoteOpenchamber: { + mode: instance?.remoteOpenchamber?.mode === 'external' ? 'external' : 'managed', + keepRunning: instance?.remoteOpenchamber?.keepRunning !== false, + ...(Number.isFinite(instance?.remoteOpenchamber?.preferredPort) ? { preferredPort: Number(instance.remoteOpenchamber.preferredPort) } : {}), + installMethod: ['npm', 'bun', 'download_release', 'upload_bundle'].includes(instance?.remoteOpenchamber?.installMethod) + ? instance.remoteOpenchamber.installMethod + : 'bun', + uploadBundleOverSsh: Boolean(instance?.remoteOpenchamber?.uploadBundleOverSsh), + }, + localForward: { + bindHost: sanitizeBindHost(instance?.localForward?.bindHost), + ...(Number.isFinite(instance?.localForward?.preferredLocalPort) ? { preferredLocalPort: Number(instance.localForward.preferredLocalPort) } : {}), + }, + auth: { + ...(this.sanitizeStoredSecret(instance?.auth?.sshPassword) ? { sshPassword: this.sanitizeStoredSecret(instance.auth.sshPassword) } : {}), + ...(this.sanitizeStoredSecret(instance?.auth?.openchamberPassword) ? { openchamberPassword: this.sanitizeStoredSecret(instance.auth.openchamberPassword) } : {}), + }, + portForwards, + }; + } + + async updateHostUrl(instanceId, label, localUrl) { + const root = readJsonRoot(this.settingsFilePath); + const hosts = Array.isArray(root.desktopHosts) ? root.desktopHosts : []; + const existing = hosts.find((entry) => entry?.id === instanceId); + if (existing) { + existing.label = label; + existing.url = localUrl; + } else { + hosts.push({ id: instanceId, label, url: localUrl }); + } + root.desktopHosts = hosts; + await writeJsonRoot(this.settingsFilePath, root); + } + + async persistLocalPort(instanceId, localPort) { + const root = readJsonRoot(this.settingsFilePath); + const instances = Array.isArray(root.desktopSshInstances) ? root.desktopSshInstances : []; + for (const instance of instances) { + if (instance?.id !== instanceId) continue; + instance.localForward = instance.localForward && typeof instance.localForward === 'object' ? instance.localForward : {}; + instance.localForward.preferredLocalPort = localPort; + } + root.desktopSshInstances = instances; + await writeJsonRoot(this.settingsFilePath, root); + } + + async resolveSshConfig(parsed) { + const { code, stdout, stderr } = await runOutput('ssh', buildSshArgs(parsed, ['-G'])); + if (code !== 0) { + throw new Error(stderr.trim() || 'Failed to resolve SSH config'); + } + const map = new Map(); + for (const line of stdout.split(/\r?\n/)) { + const trimmed = line.trim(); + if (!trimmed) continue; + const [key, ...rest] = trimmed.split(' '); + if (!key || rest.length === 0) continue; + map.set(key.toLowerCase(), rest.join(' ').trim()); + } + return map; + } + + ensureSessionDir(id) { + const base = path.join(path.dirname(this.settingsFilePath), 'ssh', id); + fs.mkdirSync(base, { recursive: true }); + return base; + } + + controlPathForInstance(id) { + let hash = 0; + for (const char of id) { + hash = ((hash << 5) - hash + char.charCodeAt(0)) | 0; + } + return path.join(os.tmpdir(), `ocssh-${Math.abs(hash).toString(16)}.sock`); + } + + async spawnMasterProcess(parsed, controlPath, askpassPath, sshPassword) { + const child = spawn('ssh', buildSshArgs(parsed, [ + '-o', 'ControlMaster=yes', + '-o', `ControlPath=${controlPath}`, + '-o', `ControlPersist=${DEFAULT_CONTROL_PERSIST_SEC}`, + '-N', + ]), { + stdio: ['ignore', 'pipe', 'pipe'], + env: { + ...process.env, + SSH_ASKPASS_REQUIRE: 'force', + SSH_ASKPASS: askpassPath, + DISPLAY: '1', + ...(sshPassword ? { OPENCHAMBER_SSH_ASKPASS_VALUE: sshPassword.trim() } : {}), + }, + }); + return child; + } + + async waitForMasterReady(parsed, controlPath, timeoutSec, master) { + const deadline = Date.now() + (timeoutSec * 1000); + let pollMs = 250; + while (Date.now() < deadline) { + const { code } = await runOutput('ssh', buildSshArgs(parsed, [ + '-o', 'ControlMaster=no', + '-o', `ControlPath=${controlPath}`, + '-O', 'check', + ])); + if (code === 0) return; + + const exited = master.exitCode; + if (typeof exited === 'number') { + throw new Error('SSH master process exited before ready'); + } + await new Promise((resolve) => setTimeout(resolve, pollMs)); + pollMs = Math.min(pollMs * 2, 2000); + } + throw new Error('SSH ControlMaster connection timed out'); + } + + configuredOpenChamberPassword(instance) { + const secret = instance?.auth?.openchamberPassword; + return secret?.enabled && typeof secret.value === 'string' && secret.value.trim() ? secret.value.trim() : null; + } + + async remoteCommandExists(parsed, controlPath, commandName) { + try { + const output = await runRemoteCommand(parsed, controlPath, `command -v ${commandName} >/dev/null 2>&1 && echo yes || echo no`); + return output.trim() === 'yes'; + } catch { + return false; + } + } + + async currentRemoteOpenChamberVersion(parsed, controlPath) { + try { + const output = await runRemoteCommand(parsed, controlPath, 'openchamber --version 2>/dev/null || true'); + return parseVersionToken(output); + } catch { + return null; + } + } + + async installOpenChamberManaged(parsed, controlPath, version, preferred) { + const hasBun = await this.remoteCommandExists(parsed, controlPath, 'bun'); + const hasNpm = await this.remoteCommandExists(parsed, controlPath, 'npm'); + const commands = []; + + if (preferred === 'bun') { + if (hasBun) commands.push(`bun add -g @openchamber/web@${version}`); + if (hasNpm) commands.push(`npm install -g @openchamber/web@${version}`); + } else if (preferred === 'npm') { + if (hasNpm) commands.push(`npm install -g @openchamber/web@${version}`); + if (hasBun) commands.push(`bun add -g @openchamber/web@${version}`); + } else { + if (hasBun) commands.push(`bun add -g @openchamber/web@${version}`); + if (hasNpm) commands.push(`npm install -g @openchamber/web@${version}`); + } + + if (commands.length === 0) { + throw new Error('Remote host has neither bun nor npm available'); + } + + let lastError = null; + for (const command of commands) { + try { + await runRemoteCommand(parsed, controlPath, command); + return; + } catch (error) { + lastError = error; + } + } + throw lastError || new Error('Failed to install OpenChamber on remote host'); + } + + async probeRemoteSystemInfo(parsed, controlPath, port, openchamberPassword) { + const authPayload = openchamberPassword ? JSON.stringify({ password: openchamberPassword }) : '{}'; + const authEnabled = openchamberPassword ? '1' : '0'; + const script = `AUTH_STATUS=0; INFO_STATUS=0; HEALTH_STATUS=0; BODY_FILE="$(mktemp)"; COOKIE_FILE="$(mktemp)"; cleanup(){ rm -f "$BODY_FILE" "$COOKIE_FILE"; }; trap cleanup EXIT; if command -v curl >/dev/null 2>&1; then if [ "${authEnabled}" = "1" ]; then AUTH_STATUS="$(curl -sS --max-time 3 -o /dev/null -w '%{http_code}' -c "$COOKIE_FILE" -H 'content-type: application/json' --data ${shellQuote(authPayload)} http://127.0.0.1:${port}/auth/session || true)"; if [ "$AUTH_STATUS" = "200" ]; then INFO_STATUS="$(curl -sS --max-time 3 -b "$COOKIE_FILE" -o "$BODY_FILE" -w '%{http_code}' http://127.0.0.1:${port}/api/system/info || true)"; else INFO_STATUS="$(curl -sS --max-time 3 -o "$BODY_FILE" -w '%{http_code}' http://127.0.0.1:${port}/api/system/info || true)"; fi; else INFO_STATUS="$(curl -sS --max-time 3 -o "$BODY_FILE" -w '%{http_code}' http://127.0.0.1:${port}/api/system/info || true)"; fi; HEALTH_STATUS="$(curl -sS --max-time 3 -o /dev/null -w '%{http_code}' http://127.0.0.1:${port}/health || true)"; elif command -v wget >/dev/null 2>&1; then wget -qO "$BODY_FILE" http://127.0.0.1:${port}/api/system/info >/dev/null 2>&1; if [ $? -eq 0 ]; then INFO_STATUS=200; fi; wget -qO- http://127.0.0.1:${port}/health >/dev/null 2>&1; if [ $? -eq 0 ]; then HEALTH_STATUS=200; fi; else exit 127; fi; printf 'INFO_STATUS=%s\\nAUTH_STATUS=%s\\nHEALTH_STATUS=%s\\n' "$INFO_STATUS" "$AUTH_STATUS" "$HEALTH_STATUS"; cat "$BODY_FILE" 2>/dev/null || true`; + const output = await runRemoteCommand(parsed, controlPath, script); + const lines = output.split(/\r?\n/); + const infoStatus = parseProbeStatusLine(lines[0], 'INFO_STATUS=') || 0; + const authStatus = parseProbeStatusLine(lines[1], 'AUTH_STATUS=') || 0; + const healthStatus = parseProbeStatusLine(lines[2], 'HEALTH_STATUS=') || 0; + const body = lines.slice(3).join('\n'); + + if (isLivenessHttpStatus(infoStatus)) { + if (isAuthHttpStatus(infoStatus)) { + if (openchamberPassword && authStatus !== 200) { + throw new Error(`Remote OpenChamber requires UI authentication and configured password was rejected (auth status ${authStatus})`); + } + if (isLivenessHttpStatus(healthStatus)) return {}; + throw new Error('Remote OpenChamber requires UI authentication on /api/system/info; configure OpenChamber UI password'); + } + } else if (isLivenessHttpStatus(healthStatus)) { + return {}; + } else { + throw new Error(`Remote OpenChamber probe failed (info status ${infoStatus}, health status ${healthStatus})`); + } + + try { + return JSON.parse(body); + } catch { + return {}; + } + } + + async remoteServerRunning(parsed, controlPath, port, openchamberPassword) { + try { + await this.probeRemoteSystemInfo(parsed, controlPath, port, openchamberPassword); + return true; + } catch { + return false; + } + } + + async startRemoteServerManaged(parsed, controlPath, instance, desiredPort) { + let envPrefix = 'OPENCHAMBER_RUNTIME=ssh-remote'; + const secret = this.configuredOpenChamberPassword(instance); + if (secret) { + envPrefix += ` OPENCHAMBER_UI_PASSWORD=${shellQuote(secret)}`; + } + const output = await runRemoteCommand(parsed, controlPath, `${envPrefix} openchamber serve --daemon --hostname 127.0.0.1 --port ${desiredPort}`); + const port = output.split(/\s+/).map((token) => Number.parseInt(token, 10)).find((value) => Number.isFinite(value)); + return port || desiredPort; + } + + async stopRemoteServerBestEffort(parsed, controlPath, remotePort) { + try { + await runRemoteCommand( + parsed, + controlPath, + `if command -v curl >/dev/null 2>&1; then curl -fsS -X POST http://127.0.0.1:${remotePort}/api/system/shutdown >/dev/null 2>&1 || true; elif command -v wget >/dev/null 2>&1; then wget -qO- --method=POST http://127.0.0.1:${remotePort}/api/system/shutdown >/dev/null 2>&1 || true; fi`, + ); + } catch { + } + } + + async spawnMainForward(parsed, controlPath, bindHost, localPort, remotePort) { + return spawn('ssh', buildSshArgs(parsed, [ + '-o', 'ControlMaster=no', + '-o', `ControlPath=${controlPath}`, + '-N', + '-L', `${bindHost}:${localPort}:127.0.0.1:${remotePort}`, + ]), { + stdio: ['ignore', 'ignore', 'pipe'], + }); + } + + async spawnExtraForward(parsed, controlPath, forward) { + const args = [ + '-o', 'ControlMaster=no', + '-o', `ControlPath=${controlPath}`, + '-O', 'forward', + ]; + if (forward.type === 'local') { + args.push('-L', `${forward.localHost || '127.0.0.1'}:${forward.localPort}:${forward.remoteHost || '127.0.0.1'}:${forward.remotePort}`); + } else if (forward.type === 'remote') { + args.push('-R', `${forward.remoteHost || '127.0.0.1'}:${forward.remotePort}:${forward.localHost || '127.0.0.1'}:${forward.localPort}`); + } else { + args.push('-D', `${forward.localHost || '127.0.0.1'}:${forward.localPort}`); + } + const { code, stdout, stderr } = await runOutput('ssh', buildSshArgs(parsed, args)); + if (code !== 0) { + throw new Error((stderr || stdout || `Failed to configure extra SSH forward ${forward.id}`).trim()); + } + } + + async ensureRemoteServer(instance, parsed, controlPath) { + if (instance.remoteOpenchamber.mode === 'external') { + if (!instance.remoteOpenchamber.preferredPort) { + throw new Error('External mode requires a preferred remote OpenChamber port'); + } + const port = instance.remoteOpenchamber.preferredPort; + this.setStatus(instance.id, 'server_detecting', 'Probing external OpenChamber server', null, null, port, false, 0, false); + await this.probeRemoteSystemInfo(parsed, controlPath, port, this.configuredOpenChamberPassword(instance)); + return { remotePort: port, startedByUs: false }; + } + + this.setStatus(instance.id, 'remote_probe', 'Checking remote OpenChamber installation'); + const installedVersion = await this.currentRemoteOpenChamberVersion(parsed, controlPath); + if (!installedVersion) { + this.setStatus(instance.id, 'installing', 'Installing OpenChamber on remote host'); + await this.installOpenChamberManaged(parsed, controlPath, this.appVersion, instance.remoteOpenchamber.installMethod); + } else if (installedVersion !== this.appVersion) { + this.setStatus(instance.id, 'updating', `Updating remote OpenChamber from ${installedVersion} to ${this.appVersion}`); + await this.installOpenChamberManaged(parsed, controlPath, this.appVersion, instance.remoteOpenchamber.installMethod); + } + + this.setStatus(instance.id, 'server_detecting', 'Detecting managed OpenChamber server'); + let remotePort = instance.remoteOpenchamber.preferredPort || null; + let startedByUs = false; + if (remotePort && !(await this.remoteServerRunning(parsed, controlPath, remotePort, this.configuredOpenChamberPassword(instance)))) { + remotePort = null; + } + if (!remotePort) { + this.setStatus(instance.id, 'server_starting', 'Starting managed OpenChamber server'); + const desiredPort = instance.remoteOpenchamber.preferredPort || randomPortCandidate(instance.id); + remotePort = await this.startRemoteServerManaged(parsed, controlPath, instance, desiredPort); + startedByUs = true; + } + if (!(await this.remoteServerRunning(parsed, controlPath, remotePort, this.configuredOpenChamberPassword(instance)))) { + throw new Error('Managed OpenChamber server failed to become reachable'); + } + return { remotePort, startedByUs }; + } + + async disconnectInternal(id, reportIdle) { + const timer = this.monitorTimers.get(id); + if (timer) { + clearTimeout(timer); + this.monitorTimers.delete(id); + } + + const session = this.sessions.get(id); + this.sessions.delete(id); + + if (session) { + if (session.startedByUs && session.instance.remoteOpenchamber.mode === 'managed' && !session.instance.remoteOpenchamber.keepRunning) { + await this.stopRemoteServerBestEffort(session.parsed, session.controlPath, session.remotePort); + } + await stopControlMasterBestEffort(session.parsed, session.controlPath); + for (const child of [session.mainForward, session.master]) { + try { + child.kill('SIGTERM'); + } catch { + } + } + try { + await fsp.rm(session.controlPath, { force: true }); + } catch { + } + try { + await fsp.rm(path.join(session.sessionDir, 'askpass.sh'), { force: true }); + } catch { + } + } + + this.clearRetryAttempt(id); + if (reportIdle) { + this.setStatus(id, 'idle', null, null, null, null, false, 0, false); + } + } + + async connectBlocking(instance) { + const id = instance.id; + this.setStatus(id, 'config_resolved', 'Resolving SSH command'); + const parsed = instance.sshParsed || parseSshCommand(instance.sshCommand); + await this.resolveSshConfig(parsed); + + this.setStatus(id, 'auth_check', 'Checking SSH connectivity'); + const sessionDir = this.ensureSessionDir(id); + const controlPath = this.controlPathForInstance(id); + try { await fsp.rm(controlPath, { force: true }); } catch {} + const askpassPath = path.join(sessionDir, 'askpass.sh'); + await writeAskpassScript(askpassPath); + + this.setStatus(id, 'master_connecting', 'Establishing SSH ControlMaster'); + const sshPassword = instance.auth?.sshPassword?.enabled ? instance.auth.sshPassword.value : null; + const master = await this.spawnMasterProcess(parsed, controlPath, askpassPath, sshPassword); + await this.waitForMasterReady(parsed, controlPath, instance.connectionTimeoutSec || DEFAULT_CONNECTION_TIMEOUT_SEC, master); + + this.setStatus(id, 'remote_probe', 'Probing remote platform'); + const remoteOs = (await runRemoteCommand(parsed, controlPath, 'uname -s', instance.connectionTimeoutSec || DEFAULT_CONNECTION_TIMEOUT_SEC)).trim().toLowerCase(); + if (!['linux', 'darwin'].includes(remoteOs)) { + master.kill('SIGTERM'); + throw new Error(`Unsupported remote OS: ${remoteOs}`); + } + + const { remotePort, startedByUs } = await this.ensureRemoteServer(instance, parsed, controlPath); + this.setStatus(id, 'forwarding', 'Setting up port forwards', null, null, remotePort, startedByUs, 0, false); + + const bindHost = sanitizeBindHost(instance.localForward?.bindHost); + let localPort = Number(instance.localForward?.preferredLocalPort) || 0; + if (!localPort) { + localPort = await pickUnusedLocalPort(); + } + if (!(await isLocalPortAvailable(bindHost, localPort))) { + localPort = await pickUnusedLocalPort(); + } + + const mainForward = await this.spawnMainForward(parsed, controlPath, bindHost, localPort, remotePort); + let mainForwardDetached = false; + await new Promise((resolve) => setTimeout(resolve, 250)); + if (typeof mainForward.exitCode === 'number') { + if (mainForward.exitCode === 0) { + mainForwardDetached = true; + this.appendLogWithLevel(id, 'INFO', 'Main tunnel helper exited after ControlMaster handoff'); + } else { + master.kill('SIGTERM'); + throw new Error(`Failed to start main port forward (status: ${mainForward.exitCode})`); + } + } + + const extraErrors = []; + for (const forward of instance.portForwards.filter((item) => item.enabled)) { + try { + await this.spawnExtraForward(parsed, controlPath, forward); + if (forward.type === 'local' && forward.localPort) { + await new Promise((resolve) => setTimeout(resolve, 100)); + if (!(await isLocalTunnelReachable(forward.localPort))) { + extraErrors.push(`${forward.id}: local listener 127.0.0.1:${forward.localPort} is not reachable`); + } + } + } catch (error) { + extraErrors.push(`${forward.id}: ${error instanceof Error ? error.message : String(error)}`); + } + } + + await waitLocalForwardReady(localPort); + + const localUrl = `http://127.0.0.1:${localPort}`; + const label = instance.nickname?.trim() || parsed.destination || id; + await this.updateHostUrl(id, label, localUrl); + if (instance.localForward?.preferredLocalPort !== localPort) { + await this.persistLocalPort(id, localPort); + } + + this.sessions.set(id, { + instance, + parsed, + sessionDir, + controlPath, + localPort, + remotePort, + startedByUs, + master, + masterDetached: false, + mainForward, + mainForwardDetached, + }); + + this.clearRetryAttempt(id); + this.setStatus( + id, + 'ready', + extraErrors.length === 0 ? 'SSH instance is ready' : `SSH instance is ready with forward warnings: ${extraErrors.join('; ')}`, + localUrl, + localPort, + remotePort, + startedByUs, + 0, + false, + ); + this.spawnMonitor(id); + } + + spawnMonitor(id) { + const existing = this.monitorTimers.get(id); + if (existing) clearTimeout(existing); + let healthyTicks = 0; + const tick = async () => { + const session = this.sessions.get(id); + if (!session) { + this.monitorTimers.delete(id); + return; + } + + let droppedReason = null; + let detachedNotice = null; + + if (!session.mainForwardDetached) { + if (typeof session.mainForward.exitCode === 'number') { + if (session.mainForward.exitCode === 0) { + session.mainForwardDetached = true; + detachedNotice = 'Main tunnel helper exited after ControlMaster handoff'; + } else { + droppedReason = `Main SSH forward exited (${session.mainForward.exitCode})`; + } + } + } + + if (!droppedReason) { + if (session.mainForwardDetached) { + // Fast path: cheap TCP probe before expensive SSH subprocess + if (await isLocalTunnelReachable(session.localPort)) { + // Tunnel alive — skip SSH check + } else if (!await isControlMasterAlive(session.parsed, session.controlPath)) { + droppedReason = 'SSH ControlMaster is not reachable'; + } else { + detachedNotice = 'Local tunnel unreachable but ControlMaster is alive'; + } + } + } + + if (detachedNotice) { + this.appendLogWithLevel(id, 'INFO', detachedNotice); + } + if (!droppedReason) { + healthyTicks++; + const pollMs = healthyTicks >= MONITOR_STABILIZE_TICKS ? MONITOR_STEADY_POLL_MS : MONITOR_INITIAL_POLL_MS; + this.monitorTimers.set(id, setTimeout(tick, pollMs)); + return; + } + + this.appendLogWithLevel(id, 'WARN', droppedReason); + await this.disconnectInternal(id, false); + const attempt = this.nextRetryAttempt(id); + if (attempt > DEFAULT_RECONNECT_MAX_ATTEMPTS) { + this.setStatus(id, 'error', `${droppedReason}. Retry limit reached`, null, null, null, false, attempt, true); + return; + } + + this.setStatus(id, 'degraded', `${droppedReason}. Reconnecting`, null, null, null, false, attempt, false); + const delayMs = Math.min((2 ** Math.max(attempt - 1, 0)) * 1000 + (nowMillis() % 700) + 100, 30000); + await new Promise((resolve) => setTimeout(resolve, delayMs)); + try { + await this.connect(id); + } catch (error) { + this.setStatus(id, 'error', error instanceof Error ? error.message : String(error), null, null, null, false, attempt, true); + } + }; + this.monitorTimers.set(id, setTimeout(tick, MONITOR_INITIAL_POLL_MS)); + } + + async connect(id) { + const trimmed = String(id || '').trim(); + if (!trimmed || trimmed === LOCAL_HOST_ID) { + throw new Error('SSH instance id is required'); + } + + if (this.connecting.has(trimmed)) { + this.appendLogWithLevel(trimmed, 'INFO', 'Connection already in progress'); + return this.connecting.get(trimmed); + } + + const instance = this.readInstances().instances.find((entry) => entry?.id === trimmed); + if (!instance) { + throw new Error('SSH instance not found'); + } + + const retryAttempt = this.currentRetryAttempt(trimmed); + const connectAttempt = this.nextConnectAttempt(trimmed); + this.appendAttemptSeparator(trimmed, connectAttempt, retryAttempt); + this.appendLog(trimmed, 'Starting SSH connection'); + await this.disconnectInternal(trimmed, false); + + const task = this.connectBlocking(this.sanitizeInstance(instance)) + .catch(async (error) => { + this.setStatus(trimmed, 'error', error instanceof Error ? error.message : String(error), null, null, null, false, 0, true); + await this.disconnectInternal(trimmed, false); + throw error; + }) + .finally(() => { + this.connecting.delete(trimmed); + }); + this.connecting.set(trimmed, task); + return task; + } + + async disconnect(id) { + const trimmed = String(id || '').trim(); + if (!trimmed || trimmed === LOCAL_HOST_ID) { + throw new Error('SSH instance id is required'); + } + await this.disconnectInternal(trimmed, true); + } + + async statusesWithDefaults(id) { + if (id) { + return [this.statusSnapshotForInstance(id)]; + } + return this.readInstances().instances + .map((instance) => this.statusSnapshotForInstance(instance.id)) + .sort((left, right) => left.id.localeCompare(right.id)); + } + + async shutdownAll() { + const ids = [...new Set([...this.sessions.keys(), ...this.connecting.keys(), ...this.monitorTimers.keys()])]; + for (const id of ids) { + await this.disconnectInternal(id, false); + } + } +} diff --git a/packages/ui/src/App.tsx b/packages/ui/src/App.tsx index a690a42e..35649756 100644 --- a/packages/ui/src/App.tsx +++ b/packages/ui/src/App.tsx @@ -35,6 +35,7 @@ import { OnboardingScreen } from '@/components/onboarding/OnboardingScreen'; import type { RecoveryVariant } from '@/components/onboarding/DesktopConnectionRecovery'; import { useSessionUIStore } from '@/sync/session-ui-store'; import { useDirectoryStore } from '@/stores/useDirectoryStore'; +import { useProjectsStore } from '@/stores/useProjectsStore'; import { opencodeClient } from '@/lib/opencode/client'; import { SyncProvider, useSessions } from '@/sync/sync-context'; import { useSync } from '@/sync/use-sync'; @@ -452,6 +453,40 @@ function App({ apis }: AppProps) { }; }, [embeddedSessionChat]); + React.useEffect(() => { + if (typeof window === 'undefined') return; + + const handler = (event: Event) => { + const detail = (event as CustomEvent<{ sessionId?: string }>).detail; + const sessionId = typeof detail?.sessionId === 'string' ? detail.sessionId.trim() : ''; + if (!sessionId) return; + void useSessionUIStore.getState().setCurrentSession(sessionId); + }; + + window.addEventListener('openchamber:open-session', handler as EventListener); + return () => window.removeEventListener('openchamber:open-session', handler as EventListener); + }, []); + + React.useEffect(() => { + if (typeof window === 'undefined') return; + + const handler = (event: Event) => { + const detail = (event as CustomEvent<{ projectPath?: string }>).detail; + const projectPath = typeof detail?.projectPath === 'string' ? detail.projectPath.trim() : ''; + if (!projectPath) return; + const projectsStore = useProjectsStore.getState(); + const existing = projectsStore.projects.find((project) => project.path === projectPath); + if (existing) { + projectsStore.setActiveProject(existing.id); + } else { + projectsStore.addProject(projectPath); + } + }; + + window.addEventListener('openchamber:open-project', handler as EventListener); + return () => window.removeEventListener('openchamber:open-project', handler as EventListener); + }, []); + React.useEffect(() => { if (typeof window === 'undefined') return; if (!isInitialized || isSwitchingDirectory) return; diff --git a/packages/ui/src/components/chat/ChatInput.tsx b/packages/ui/src/components/chat/ChatInput.tsx index 5b7b8508..b0cf079e 100644 --- a/packages/ui/src/components/chat/ChatInput.tsx +++ b/packages/ui/src/components/chat/ChatInput.tsx @@ -756,7 +756,7 @@ const ChatInputComponent: React.FC = ({ onOpenSettings, scrollTo const composerHighlightRef = React.useRef(null); const isDesktopExpanded = isExpandedInput && !isMobile; - const chatInputRadius = 'var(--radius-lg)'; + const chatInputRadius = 'var(--radius-xl)'; const sendableAttachedFiles = attachedFiles; diff --git a/packages/ui/src/components/chat/ChatMessage.tsx b/packages/ui/src/components/chat/ChatMessage.tsx index 53fe4475..68e63bf5 100644 --- a/packages/ui/src/components/chat/ChatMessage.tsx +++ b/packages/ui/src/components/chat/ChatMessage.tsx @@ -966,7 +966,7 @@ const ChatMessage: React.FC = ({ const assistantTopPaddingClass = !isUser && shouldShowHeader ? (stickyUserHeader ? (isMobile ? 'pt-4' : 'pt-6') : 'pt-0') : 'pt-0'; - const userMessageRadius = 'var(--radius-lg)'; + const userMessageRadius = 'var(--radius-xl)'; return ( <> diff --git a/packages/ui/src/components/chat/components/ScrollToBottomButton.tsx b/packages/ui/src/components/chat/components/ScrollToBottomButton.tsx index 1971bacd..c3234ae4 100644 --- a/packages/ui/src/components/chat/components/ScrollToBottomButton.tsx +++ b/packages/ui/src/components/chat/components/ScrollToBottomButton.tsx @@ -21,7 +21,7 @@ const ScrollToBottomButton: React.FC = ({ visible, on variant="outline" size="sm" onClick={onClick} - className="rounded-full h-8 w-8 p-0 shadow-none bg-background/95 hover:bg-interactive-hover" + className="size-8 rounded-full [corner-shape:round] p-0 shadow-none bg-background/95 hover:bg-interactive-hover" aria-label="Scroll to bottom" > diff --git a/packages/ui/src/components/desktop/DesktopHostSwitcher.tsx b/packages/ui/src/components/desktop/DesktopHostSwitcher.tsx index a9d560c0..7109bf13 100644 --- a/packages/ui/src/components/desktop/DesktopHostSwitcher.tsx +++ b/packages/ui/src/components/desktop/DesktopHostSwitcher.tsx @@ -549,6 +549,10 @@ export function DesktopHostSwitcherDialog({ setEditUrl(''); }, []); + const stopDropdownTypeahead = React.useCallback((event: React.KeyboardEvent) => { + event.stopPropagation(); + }, []); + const commitEdit = React.useCallback(async () => { if (!editingId) return; if (editingId === LOCAL_HOST_ID) { @@ -972,12 +976,14 @@ export function DesktopHostSwitcherDialog({ setEditLabel(e.target.value)} + onKeyDown={stopDropdownTypeahead} placeholder="Label" disabled={isSaving} /> setEditUrl(e.target.value)} + onKeyDown={stopDropdownTypeahead} placeholder="https://host:port" disabled={isSaving} /> @@ -1033,12 +1039,14 @@ export function DesktopHostSwitcherDialog({ setNewLabel(e.target.value)} + onKeyDown={stopDropdownTypeahead} placeholder="Label (optional)" disabled={!tauriAvailable || isSaving} /> setNewUrl(e.target.value)} + onKeyDown={stopDropdownTypeahead} placeholder="https://host:port" disabled={!tauriAvailable || isSaving} /> diff --git a/packages/ui/src/components/desktop/OpenInAppButton.tsx b/packages/ui/src/components/desktop/OpenInAppButton.tsx index 15938b52..8be58585 100644 --- a/packages/ui/src/components/desktop/OpenInAppButton.tsx +++ b/packages/ui/src/components/desktop/OpenInAppButton.tsx @@ -69,11 +69,10 @@ const AppIcon = ({ type OpenInAppButtonProps = { directory: string; - activeFilePath?: string | null; className?: string; }; -export const OpenInAppButton = ({ directory, activeFilePath, className }: OpenInAppButtonProps) => { +export const OpenInAppButton = ({ directory, className }: OpenInAppButtonProps) => { const selectedAppId = useOpenInAppsStore((state) => state.selectedAppId); const availableApps = useOpenInAppsStore((state) => state.availableApps); const isCacheStale = useOpenInAppsStore((state) => state.isCacheStale); @@ -108,7 +107,7 @@ export const OpenInAppButton = ({ directory, activeFilePath, className }: OpenIn } const handleOpen = async (app: OpenInAppOption) => { - const opened = await openDesktopProjectInApp(directory, app.id, app.appName, activeFilePath); + const opened = await openDesktopProjectInApp(directory, app.id, app.appName); if (!opened) { await openDesktopPath(directory, app.appName); } diff --git a/packages/ui/src/components/layout/Header.tsx b/packages/ui/src/components/layout/Header.tsx index ae29420e..183dc34e 100644 --- a/packages/ui/src/components/layout/Header.tsx +++ b/packages/ui/src/components/layout/Header.tsx @@ -27,7 +27,6 @@ import { useAllLiveSessions, useSession, useSessionMessagesResolved } from '@/sy import { getAllSyncSessions } from '@/sync/sync-refs'; import { useProjectsStore } from '@/stores/useProjectsStore'; import { useQuotaAutoRefresh, useQuotaStore } from '@/stores/useQuotaStore'; -import { useFilesViewTabsStore } from '@/stores/useFilesViewTabsStore'; import { useGitBranchLabel } from '@/stores/useGitStore'; import { useGlobalSessionsStore } from '@/stores/useGlobalSessionsStore'; import { useFeatureFlagsStore } from '@/stores/useFeatureFlagsStore'; @@ -1105,14 +1104,6 @@ export const Header: React.FC = ({ }, [currentSessionDiffStats]); const hasNonZeroSessionChanges = currentSessionChanges.additions > 0 || currentSessionChanges.deletions > 0; - const selectedFilePath = useFilesViewTabsStore((state) => { - const directory = normalize(openDirectory || ''); - if (!directory) { - return null; - } - return state.byRoot[directory]?.selectedPath ?? null; - }); - const actionDirectory = React.useMemo(() => { return normalize(openDirectory || activeProject?.path || ''); }, [activeProject?.path, openDirectory]); @@ -1643,7 +1634,7 @@ export const Header: React.FC = ({ )} - + = ({ {todos.map((todo) => { const isExpandedTodo = expandedTodoIds.has(todo.id); return ( -
  • - handleToggleTodo(todo.id, checked)} - ariaLabel={`Mark "${todo.text}" complete`} - className="mt-[3px] self-start" - /> - -
    +
  • +
    + handleToggleTodo(todo.id, checked)} + ariaLabel={`Mark "${todo.text}" complete`} + /> +
    - - - - - - handleSendToCurrentSession(todo.text)}> - Send to current session - - handleSendToNewSession(todo.id, todo.text)}> - Send to new session - - void handleSendToNewWorktreeSession(todo.id, todo.text)} - disabled={!canCreateWorktree} - > - Send to new worktree session - - - - -
  • +
    + + + + + + + handleSendToCurrentSession(todo.text)}> + Send to current session + + handleSendToNewSession(todo.id, todo.text)}> + Send to new session + + void handleSendToNewWorktreeSession(todo.id, todo.text)} + disabled={!canCreateWorktree} + > + Send to new worktree session + + + +
    + ); })} diff --git a/packages/ui/src/components/session/SessionSidebar.tsx b/packages/ui/src/components/session/SessionSidebar.tsx index dc8deafd..6a28a67e 100644 --- a/packages/ui/src/components/session/SessionSidebar.tsx +++ b/packages/ui/src/components/session/SessionSidebar.tsx @@ -3,7 +3,8 @@ import type { Session } from '@opencode-ai/sdk/v2'; import { RiLayoutLeftLine } from '@remixicon/react'; import { toast } from '@/components/ui'; import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; -import { isDesktopLocalOriginActive, isDesktopShell, isTauriShell, startDesktopWindowDrag } from '@/lib/desktop'; +import { isDesktopLocalOriginActive, isDesktopShell, isTauriShell } from '@/lib/desktop'; +import { isDesktopWindowFullscreen as getDesktopWindowFullscreen, onDesktopWindowResized, startDesktopWindowDrag } from '@/lib/desktopNative'; import { sessionEvents } from '@/lib/sessionEvents'; import { formatDirectoryName, cn } from '@/lib/utils'; import { useSessionUIStore } from '@/sync/session-ui-store'; @@ -403,9 +404,7 @@ export const SessionSidebar: React.FC = ({ const syncFullscreenState = async () => { try { - const { getCurrentWindow } = await import('@tauri-apps/api/window'); - const currentWindow = getCurrentWindow(); - const fullscreen = await currentWindow.isFullscreen(); + const fullscreen = await getDesktopWindowFullscreen(); if (!disposed) { setIsDesktopWindowFullscreen(fullscreen); } @@ -418,9 +417,7 @@ export const SessionSidebar: React.FC = ({ const attach = async () => { try { - const { getCurrentWindow } = await import('@tauri-apps/api/window'); - const currentWindow = getCurrentWindow(); - unlistenResize = await currentWindow.onResized(() => { + unlistenResize = onDesktopWindowResized(() => { void syncFullscreenState(); }); } catch { diff --git a/packages/ui/src/components/views/FilesView.tsx b/packages/ui/src/components/views/FilesView.tsx index a35741c0..7ab196e2 100644 --- a/packages/ui/src/components/views/FilesView.tsx +++ b/packages/ui/src/components/views/FilesView.tsx @@ -80,8 +80,7 @@ import { useEffectiveDirectory } from '@/hooks/useEffectiveDirectory'; import { FileTypeIcon } from '@/components/icons/FileTypeIcon'; import { ensurePierreThemeRegistered } from '@/lib/shiki/appThemeRegistry'; import { getDefaultTheme } from '@/lib/theme/themes'; -import { openDesktopPath, openDesktopProjectInApp } from '@/lib/desktop'; -import { OPEN_DIRECTORY_APP_IDS } from '@/lib/openInApps'; +import { openDesktopFileInApp, openDesktopPath } from '@/lib/desktop'; import { useOpenInAppsStore } from '@/stores/useOpenInAppsStore'; import { eventMatchesShortcut, getEffectiveShortcutCombo } from '@/lib/shortcuts'; @@ -510,17 +509,32 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { const [isSearchOpen, setIsSearchOpen] = React.useState(false); const [isFloatingToolbarOpen, setIsFloatingToolbarOpen] = React.useState(false); const floatingToolbarRef = React.useRef(null); + const toolbarDropdownOpenCountRef = React.useRef(0); + + const handleToolbarDropdownOpenChange = React.useCallback((open: boolean) => { + toolbarDropdownOpenCountRef.current = Math.max( + 0, + toolbarDropdownOpenCountRef.current + (open ? 1 : -1), + ); + }, []); + + const isClickInsidePortalledMenu = React.useCallback((target: EventTarget | null) => { + if (!(target instanceof Element)) return false; + return target.closest('[data-slot="dropdown-menu-content"], [data-slot="dropdown-menu-item"]') !== null; + }, []); React.useEffect(() => { if (!isFloatingToolbarOpen) return; const handler = (event: MouseEvent) => { + if (toolbarDropdownOpenCountRef.current > 0) return; + if (isClickInsidePortalledMenu(event.target)) return; if (floatingToolbarRef.current && !floatingToolbarRef.current.contains(event.target as Node)) { setIsFloatingToolbarOpen(false); } }; document.addEventListener('mousedown', handler); return () => document.removeEventListener('mousedown', handler); - }, [isFloatingToolbarOpen]); + }, [isClickInsidePortalledMenu, isFloatingToolbarOpen]); const [textViewMode, setTextViewMode] = React.useState<'view' | 'edit'>('edit'); const [mdViewMode, setMdViewMode] = React.useState<'preview' | 'edit'>('edit'); const [jsonViewMode, setJsonViewMode] = React.useState<'tree' | 'text'>('tree'); @@ -664,21 +678,11 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { }, [files]); const handleOpenInApp = React.useCallback(async (app: { id: string; appName: string }) => { - if (!selectedFile?.path || !root) { + if (!selectedFile?.path) { return; } - const fileDirectory = getParentDirectoryPath(selectedFile.path) || root; - - if (OPEN_DIRECTORY_APP_IDS.has(app.id)) { - const openedDirectory = await openDesktopPath(fileDirectory, app.appName); - if (!openedDirectory) { - toast.error(`Failed to open in ${app.appName}`); - } - return; - } - - const openedInApp = await openDesktopProjectInApp(root, app.id, app.appName, selectedFile.path); + const openedInApp = await openDesktopFileInApp(selectedFile.path, app.id, app.appName); if (openedInApp) { return; } @@ -688,10 +692,14 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { return; } - const openedDirectory = await openDesktopPath(fileDirectory, app.appName); - if (!openedDirectory) { - toast.error(`Failed to open in ${app.appName}`); + const fileDirectory = getParentDirectoryPath(selectedFile.path) || root; + if (fileDirectory) { + const openedDirectory = await openDesktopPath(fileDirectory, app.appName); + if (openedDirectory) { + return; + } } + toast.error(`Failed to open in ${app.appName}`); }, [root, selectedFile?.path]); const handleOpenDialog = React.useCallback((type: 'createFile' | 'createFolder' | 'rename' | 'delete', data: { path: string; name?: string; type?: 'file' | 'directory' }) => { @@ -2354,7 +2362,7 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { ) : null )} - +