mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 19:54:44 -07:00
optionally (default off) allow keep gerbil in the tray, fix moe expert updating, dep upgrades, moving things to a new troubleshooting setting tab
This commit is contained in:
parent
fd2db3e40e
commit
0f214bdbe2
22 changed files with 754 additions and 362 deletions
22
package.json
22
package.json
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "gerbil",
|
"name": "gerbil",
|
||||||
"productName": "Gerbil",
|
"productName": "Gerbil",
|
||||||
"version": "1.6.1",
|
"version": "1.6.2",
|
||||||
"description": "Run Large Language Models locally",
|
"description": "Run Large Language Models locally",
|
||||||
"main": "out/main/index.js",
|
"main": "out/main/index.js",
|
||||||
"homepage": "./",
|
"homepage": "./",
|
||||||
|
|
@ -39,14 +39,14 @@
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.36.0",
|
"@eslint/js": "^9.36.0",
|
||||||
"@types/node": "^24.5.2",
|
"@types/node": "^24.6.1",
|
||||||
"@types/react": "^19.1.14",
|
"@types/react": "^19.1.16",
|
||||||
"@types/react-dom": "^19.1.9",
|
"@types/react-dom": "^19.1.9",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.44.1",
|
"@typescript-eslint/eslint-plugin": "^8.45.0",
|
||||||
"@typescript-eslint/parser": "^8.44.1",
|
"@typescript-eslint/parser": "^8.45.0",
|
||||||
"@vitejs/plugin-react": "^5.0.3",
|
"@vitejs/plugin-react": "^5.0.4",
|
||||||
"cross-env": "^10.0.0",
|
"cross-env": "^10.1.0",
|
||||||
"electron": "^38.1.2",
|
"electron": "^38.2.0",
|
||||||
"electron-builder": "^26.0.12",
|
"electron-builder": "^26.0.12",
|
||||||
"electron-vite": "^4.0.1",
|
"electron-vite": "^4.0.1",
|
||||||
"eslint": "^9.36.0",
|
"eslint": "^9.36.0",
|
||||||
|
|
@ -60,13 +60,13 @@
|
||||||
"jiti": "^2.6.0",
|
"jiti": "^2.6.0",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"rollup-plugin-visualizer": "^6.0.3",
|
"rollup-plugin-visualizer": "^6.0.3",
|
||||||
"typescript": "^5.9.2",
|
"typescript": "^5.9.3",
|
||||||
"vite": "^7.1.7"
|
"vite": "^7.1.7"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/search": "^6.5.11",
|
"@codemirror/search": "^6.5.11",
|
||||||
"@codemirror/theme-one-dark": "^6.1.3",
|
"@codemirror/theme-one-dark": "^6.1.3",
|
||||||
"@codemirror/view": "^6.38.3",
|
"@codemirror/view": "^6.38.4",
|
||||||
"@fontsource/inter": "^5.2.8",
|
"@fontsource/inter": "^5.2.8",
|
||||||
"@mantine/core": "8.3.1",
|
"@mantine/core": "8.3.1",
|
||||||
"@mantine/hooks": "8.3.1",
|
"@mantine/hooks": "8.3.1",
|
||||||
|
|
@ -79,7 +79,7 @@
|
||||||
"react-dom": "^19.1.1",
|
"react-dom": "^19.1.1",
|
||||||
"react-error-boundary": "^6.0.0",
|
"react-error-boundary": "^6.0.0",
|
||||||
"systeminformation": "^5.27.10",
|
"systeminformation": "^5.27.10",
|
||||||
"winston": "^3.17.0",
|
"winston": "^3.18.3",
|
||||||
"winston-daily-rotate-file": "^5.0.0",
|
"winston-daily-rotate-file": "^5.0.0",
|
||||||
"yauzl": "^3.2.0",
|
"yauzl": "^3.2.0",
|
||||||
"zustand": "^5.0.8"
|
"zustand": "^5.0.8"
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import { NotepadContainer } from '@/components/Notepad/Container';
|
||||||
import { useUpdateChecker } from '@/hooks/useUpdateChecker';
|
import { useUpdateChecker } from '@/hooks/useUpdateChecker';
|
||||||
import { useKoboldVersionsStore } from '@/stores/koboldVersions';
|
import { useKoboldVersionsStore } from '@/stores/koboldVersions';
|
||||||
import { usePreferencesStore } from '@/stores/preferences';
|
import { usePreferencesStore } from '@/stores/preferences';
|
||||||
|
import { useLaunchConfigStore } from '@/stores/launchConfig';
|
||||||
import { STATUSBAR_HEIGHT, TITLEBAR_HEIGHT } from '@/constants';
|
import { STATUSBAR_HEIGHT, TITLEBAR_HEIGHT } from '@/constants';
|
||||||
import type { DownloadItem } from '@/types/electron';
|
import type { DownloadItem } from '@/types/electron';
|
||||||
import type { InterfaceTab, Screen } from '@/types';
|
import type { InterfaceTab, Screen } from '@/types';
|
||||||
|
|
@ -29,13 +30,44 @@ export const App = () => {
|
||||||
const [ejectConfirmModalOpen, setEjectConfirmModalOpen] = useState(false);
|
const [ejectConfirmModalOpen, setEjectConfirmModalOpen] = useState(false);
|
||||||
const isInterfaceScreen = currentScreen === 'interface';
|
const isInterfaceScreen = currentScreen === 'interface';
|
||||||
|
|
||||||
const { resolvedColorScheme: appColorScheme } = usePreferencesStore();
|
const { resolvedColorScheme: appColorScheme, systemMonitoringEnabled } =
|
||||||
|
usePreferencesStore();
|
||||||
const { setColorScheme } = useMantineColorScheme();
|
const { setColorScheme } = useMantineColorScheme();
|
||||||
|
const { model, sdmodel } = useLaunchConfigStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setColorScheme(appColorScheme);
|
setColorScheme(appColorScheme);
|
||||||
}, [appColorScheme, setColorScheme]);
|
}, [appColorScheme, setColorScheme]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const updateTray = async () => {
|
||||||
|
const config = await window.electronAPI.kobold.getSelectedConfig();
|
||||||
|
const displayModel = model || sdmodel || null;
|
||||||
|
const modelName = displayModel
|
||||||
|
? displayModel.split('/').pop() || displayModel
|
||||||
|
: null;
|
||||||
|
|
||||||
|
window.electronAPI.app.updateTrayState({
|
||||||
|
screen: currentScreen,
|
||||||
|
model: modelName,
|
||||||
|
config: config || null,
|
||||||
|
monitoringEnabled: systemMonitoringEnabled,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
void updateTray();
|
||||||
|
}, [currentScreen, model, sdmodel, systemMonitoringEnabled]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const ejectCleanup = window.electronAPI.app.onTrayEject(() => {
|
||||||
|
performEject();
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
ejectCleanup();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
updateInfo: binaryUpdateInfo,
|
updateInfo: binaryUpdateInfo,
|
||||||
showUpdateModal,
|
showUpdateModal,
|
||||||
|
|
|
||||||
|
|
@ -167,14 +167,11 @@ export const AdvancedTab = () => {
|
||||||
</Group>
|
</Group>
|
||||||
<NumberInput
|
<NumberInput
|
||||||
value={moeexperts}
|
value={moeexperts}
|
||||||
onChange={(value) =>
|
onChange={(value) => handleMoeexpertsChange(Number(value))}
|
||||||
handleMoeexpertsChange(Number(value) || -1)
|
|
||||||
}
|
|
||||||
min={-1}
|
min={-1}
|
||||||
max={128}
|
max={128}
|
||||||
step={1}
|
step={1}
|
||||||
size="sm"
|
size="sm"
|
||||||
placeholder="-1"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -192,7 +189,6 @@ export const AdvancedTab = () => {
|
||||||
max={999}
|
max={999}
|
||||||
step={1}
|
step={1}
|
||||||
size="sm"
|
size="sm"
|
||||||
placeholder="0"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
|
||||||
|
|
@ -261,7 +261,7 @@ export const LaunchScreen = ({ onLaunch }: LaunchScreenProps) => {
|
||||||
return cleanup;
|
return cleanup;
|
||||||
}, [loadConfigFiles]);
|
}, [loadConfigFiles]);
|
||||||
|
|
||||||
const handleLaunchClick = () => {
|
const handleLaunchClick = useCallback(() => {
|
||||||
handleLaunch({
|
handleLaunch({
|
||||||
autoGpuLayers,
|
autoGpuLayers,
|
||||||
gpuLayers,
|
gpuLayers,
|
||||||
|
|
@ -295,7 +295,51 @@ export const LaunchScreen = ({ onLaunch }: LaunchScreenProps) => {
|
||||||
moecpu,
|
moecpu,
|
||||||
moeexperts,
|
moeexperts,
|
||||||
});
|
});
|
||||||
};
|
}, [
|
||||||
|
handleLaunch,
|
||||||
|
autoGpuLayers,
|
||||||
|
gpuLayers,
|
||||||
|
contextSize,
|
||||||
|
port,
|
||||||
|
host,
|
||||||
|
multiuser,
|
||||||
|
multiplayer,
|
||||||
|
remotetunnel,
|
||||||
|
nocertify,
|
||||||
|
websearch,
|
||||||
|
noshift,
|
||||||
|
flashattention,
|
||||||
|
noavx2,
|
||||||
|
failsafe,
|
||||||
|
backend,
|
||||||
|
lowvram,
|
||||||
|
gpuDeviceSelection,
|
||||||
|
gpuPlatform,
|
||||||
|
tensorSplit,
|
||||||
|
quantmatmul,
|
||||||
|
usemmap,
|
||||||
|
additionalArguments,
|
||||||
|
sdt5xxl,
|
||||||
|
sdclipl,
|
||||||
|
sdclipg,
|
||||||
|
sdphotomaker,
|
||||||
|
sdvae,
|
||||||
|
sdlora,
|
||||||
|
sdconvdirect,
|
||||||
|
moecpu,
|
||||||
|
moeexperts,
|
||||||
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const cleanup = window.electronAPI.app.onTrayLaunch(() => {
|
||||||
|
if (!model && !sdmodel) return;
|
||||||
|
if (isLaunching) return;
|
||||||
|
|
||||||
|
handleLaunchClick();
|
||||||
|
});
|
||||||
|
|
||||||
|
return cleanup;
|
||||||
|
}, [model, sdmodel, isLaunching, handleLaunchClick]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container size="sm" mt="md">
|
<Container size="sm" mt="md">
|
||||||
|
|
|
||||||
|
|
@ -1,85 +1,28 @@
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import {
|
import { Stack, Text, Switch } from '@mantine/core';
|
||||||
Stack,
|
|
||||||
Text,
|
|
||||||
Group,
|
|
||||||
TextInput,
|
|
||||||
Button,
|
|
||||||
rem,
|
|
||||||
Switch,
|
|
||||||
} from '@mantine/core';
|
|
||||||
import { Folder, FolderOpen, Monitor, ExternalLink } from 'lucide-react';
|
|
||||||
import { usePreferencesStore } from '@/stores/preferences';
|
import { usePreferencesStore } from '@/stores/preferences';
|
||||||
|
|
||||||
export const GeneralTab = () => {
|
export const GeneralTab = () => {
|
||||||
const [installDir, setInstallDir] = useState('');
|
const [enableSystemTray, setEnableSystemTray] = useState(false);
|
||||||
const { systemMonitoringEnabled, setSystemMonitoringEnabled } =
|
const { systemMonitoringEnabled, setSystemMonitoringEnabled } =
|
||||||
usePreferencesStore();
|
usePreferencesStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadCurrentInstallDir();
|
loadSystemTrayPreference();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const loadCurrentInstallDir = async () => {
|
const loadSystemTrayPreference = async () => {
|
||||||
const currentDir = await window.electronAPI.kobold.getCurrentInstallDir();
|
const enabled = await window.electronAPI.app.getEnableSystemTray();
|
||||||
if (currentDir) {
|
setEnableSystemTray(enabled);
|
||||||
setInstallDir(currentDir);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectInstallDir = async () => {
|
const handleSystemTrayToggle = async (checked: boolean) => {
|
||||||
const selectedDir =
|
setEnableSystemTray(checked);
|
||||||
await window.electronAPI.kobold.selectInstallDirectory();
|
await window.electronAPI.app.setEnableSystemTray(checked);
|
||||||
if (selectedDir) {
|
|
||||||
setInstallDir(selectedDir);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleOpenInstallDir = async () => {
|
|
||||||
if (installDir) {
|
|
||||||
await window.electronAPI.app.openPath(installDir);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack gap="lg" h="100%">
|
<Stack gap="lg" h="100%">
|
||||||
<div>
|
|
||||||
<Text fw={500} mb="sm">
|
|
||||||
Installation Directory
|
|
||||||
</Text>
|
|
||||||
<Text size="sm" c="dimmed" mb="md">
|
|
||||||
Choose where application files will be downloaded and stored
|
|
||||||
</Text>
|
|
||||||
<Group gap="xs">
|
|
||||||
<TextInput
|
|
||||||
value={installDir}
|
|
||||||
readOnly
|
|
||||||
placeholder="Default installation directory"
|
|
||||||
style={{ flex: 1 }}
|
|
||||||
leftSection={<Folder style={{ width: rem(16), height: rem(16) }} />}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
onClick={handleSelectInstallDir}
|
|
||||||
leftSection={
|
|
||||||
<FolderOpen style={{ width: rem(16), height: rem(16) }} />
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Browse
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
onClick={handleOpenInstallDir}
|
|
||||||
disabled={!installDir}
|
|
||||||
leftSection={
|
|
||||||
<ExternalLink style={{ width: rem(16), height: rem(16) }} />
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Open
|
|
||||||
</Button>
|
|
||||||
</Group>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Text fw={500} mb="sm">
|
<Text fw={500} mb="sm">
|
||||||
Status Bar
|
Status Bar
|
||||||
|
|
@ -98,33 +41,19 @@ export const GeneralTab = () => {
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Text fw={500} mb="sm">
|
<Text fw={500} mb="sm">
|
||||||
Troubleshooting
|
System Tray
|
||||||
</Text>
|
</Text>
|
||||||
<Text size="sm" c="dimmed" mb="md">
|
<Text size="sm" c="dimmed" mb="md">
|
||||||
Diagnostic tools and configuration access
|
Add a system tray icon with quick access to launch, eject, and monitor
|
||||||
|
system metrics
|
||||||
</Text>
|
</Text>
|
||||||
<Group gap="xs">
|
<Switch
|
||||||
<Button
|
label="Enable system tray icon"
|
||||||
variant="outline"
|
checked={enableSystemTray}
|
||||||
size="compact-sm"
|
onChange={(event) =>
|
||||||
leftSection={
|
handleSystemTrayToggle(event.currentTarget.checked)
|
||||||
<FolderOpen style={{ width: rem(16), height: rem(16) }} />
|
|
||||||
}
|
}
|
||||||
onClick={() => window.electronAPI.app.showLogsFolder()}
|
/>
|
||||||
>
|
|
||||||
Show Logs
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="compact-sm"
|
|
||||||
leftSection={
|
|
||||||
<Monitor style={{ width: rem(16), height: rem(16) }} />
|
|
||||||
}
|
|
||||||
onClick={() => window.electronAPI.app.viewConfigFile()}
|
|
||||||
>
|
|
||||||
View Config
|
|
||||||
</Button>
|
|
||||||
</Group>
|
|
||||||
</div>
|
</div>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,13 @@ import {
|
||||||
GitBranch,
|
GitBranch,
|
||||||
Monitor,
|
Monitor,
|
||||||
Info,
|
Info,
|
||||||
|
Wrench,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { GeneralTab } from '@/components/settings/GeneralTab';
|
import { GeneralTab } from '@/components/settings/GeneralTab';
|
||||||
import { VersionsTab } from '@/components/settings/VersionsTab';
|
import { VersionsTab } from '@/components/settings/VersionsTab';
|
||||||
import { AppearanceTab } from '@/components/settings/AppearanceTab';
|
import { AppearanceTab } from '@/components/settings/AppearanceTab';
|
||||||
import { SystemTab } from '@/components/settings/SystemTab';
|
import { SystemTab } from '@/components/settings/SystemTab';
|
||||||
|
import { TroubleshootingTab } from '@/components/settings/TroubleshootingTab';
|
||||||
import { AboutTab } from '@/components/settings/AboutTab';
|
import { AboutTab } from '@/components/settings/AboutTab';
|
||||||
import type { Screen } from '@/types';
|
import type { Screen } from '@/types';
|
||||||
import { Modal } from '@/components/Modal';
|
import { Modal } from '@/components/Modal';
|
||||||
|
|
@ -139,6 +141,14 @@ export const SettingsModal = ({
|
||||||
>
|
>
|
||||||
System
|
System
|
||||||
</Tabs.Tab>
|
</Tabs.Tab>
|
||||||
|
<Tabs.Tab
|
||||||
|
value="troubleshooting"
|
||||||
|
leftSection={
|
||||||
|
<Wrench style={{ width: rem(16), height: rem(16) }} />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Troubleshooting
|
||||||
|
</Tabs.Tab>
|
||||||
<Tabs.Tab
|
<Tabs.Tab
|
||||||
value="about"
|
value="about"
|
||||||
leftSection={<Info style={{ width: rem(16), height: rem(16) }} />}
|
leftSection={<Info style={{ width: rem(16), height: rem(16) }} />}
|
||||||
|
|
@ -165,6 +175,10 @@ export const SettingsModal = ({
|
||||||
<SystemTab />
|
<SystemTab />
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
|
|
||||||
|
<Tabs.Panel value="troubleshooting">
|
||||||
|
<TroubleshootingTab />
|
||||||
|
</Tabs.Panel>
|
||||||
|
|
||||||
<Tabs.Panel value="about">
|
<Tabs.Panel value="about">
|
||||||
<AboutTab />
|
<AboutTab />
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
|
|
|
||||||
104
src/components/settings/TroubleshootingTab.tsx
Normal file
104
src/components/settings/TroubleshootingTab.tsx
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { Stack, Text, Group, TextInput, Button, rem } from '@mantine/core';
|
||||||
|
import { Folder, FolderOpen, Monitor, ExternalLink } from 'lucide-react';
|
||||||
|
|
||||||
|
export const TroubleshootingTab = () => {
|
||||||
|
const [installDir, setInstallDir] = useState('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadCurrentInstallDir();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const loadCurrentInstallDir = async () => {
|
||||||
|
const currentDir = await window.electronAPI.kobold.getCurrentInstallDir();
|
||||||
|
if (currentDir) {
|
||||||
|
setInstallDir(currentDir);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelectInstallDir = async () => {
|
||||||
|
const selectedDir =
|
||||||
|
await window.electronAPI.kobold.selectInstallDirectory();
|
||||||
|
if (selectedDir) {
|
||||||
|
setInstallDir(selectedDir);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOpenInstallDir = async () => {
|
||||||
|
if (installDir) {
|
||||||
|
await window.electronAPI.app.openPath(installDir);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack gap="lg" h="100%">
|
||||||
|
<div>
|
||||||
|
<Text fw={500} mb="sm">
|
||||||
|
Installation Directory
|
||||||
|
</Text>
|
||||||
|
<Text size="sm" c="dimmed" mb="md">
|
||||||
|
Choose where application files will be downloaded and stored
|
||||||
|
</Text>
|
||||||
|
<Group gap="xs">
|
||||||
|
<TextInput
|
||||||
|
value={installDir}
|
||||||
|
readOnly
|
||||||
|
placeholder="Default installation directory"
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
leftSection={<Folder style={{ width: rem(16), height: rem(16) }} />}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={handleSelectInstallDir}
|
||||||
|
leftSection={
|
||||||
|
<FolderOpen style={{ width: rem(16), height: rem(16) }} />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Browse
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={handleOpenInstallDir}
|
||||||
|
disabled={!installDir}
|
||||||
|
leftSection={
|
||||||
|
<ExternalLink style={{ width: rem(16), height: rem(16) }} />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Open
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Text fw={500} mb="sm">
|
||||||
|
Diagnostics
|
||||||
|
</Text>
|
||||||
|
<Text size="sm" c="dimmed" mb="md">
|
||||||
|
Diagnostic tools and configuration access
|
||||||
|
</Text>
|
||||||
|
<Group gap="xs">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="compact-sm"
|
||||||
|
leftSection={
|
||||||
|
<FolderOpen style={{ width: rem(16), height: rem(16) }} />
|
||||||
|
}
|
||||||
|
onClick={() => window.electronAPI.app.showLogsFolder()}
|
||||||
|
>
|
||||||
|
Show Logs
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="compact-sm"
|
||||||
|
leftSection={
|
||||||
|
<Monitor style={{ width: rem(16), height: rem(16) }} />
|
||||||
|
}
|
||||||
|
onClick={() => window.electronAPI.app.viewConfigFile()}
|
||||||
|
>
|
||||||
|
View Config
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</div>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -9,6 +9,7 @@ import {
|
||||||
initialize as initializeConfig,
|
initialize as initializeConfig,
|
||||||
getInstallDir,
|
getInstallDir,
|
||||||
} from '@/main/modules/config';
|
} from '@/main/modules/config';
|
||||||
|
import { createTray } from '@/main/modules/tray';
|
||||||
import { safeExecute } from '@/utils/node/logging';
|
import { safeExecute } from '@/utils/node/logging';
|
||||||
import { stopKoboldCpp } from '@/main/modules/koboldcpp/launcher';
|
import { stopKoboldCpp } from '@/main/modules/koboldcpp/launcher';
|
||||||
import { stopFrontend as stopSillyTavern } from '@/main/modules/sillytavern';
|
import { stopFrontend as stopSillyTavern } from '@/main/modules/sillytavern';
|
||||||
|
|
@ -27,6 +28,7 @@ export async function initializeApp() {
|
||||||
await ensureDir(installDir);
|
await ensureDir(installDir);
|
||||||
|
|
||||||
createMainWindow();
|
createMainWindow();
|
||||||
|
createTray();
|
||||||
|
|
||||||
setupIPCHandlers();
|
setupIPCHandlers();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { argv, exit } from 'process';
|
import { argv, exit } from 'process';
|
||||||
import { getAppVersion } from '@/utils/node/fs';
|
|
||||||
|
|
||||||
if (argv[1] === '--version') {
|
if (argv[1] === '--version') {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const version = await getAppVersion();
|
const { app } = await import('electron');
|
||||||
|
const version = await app.getVersion();
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(version);
|
console.log(version);
|
||||||
} catch {
|
} catch {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { ipcMain, app } from 'electron';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { release } from 'os';
|
import { release } from 'os';
|
||||||
import { platform, versions, arch } from 'process';
|
import { platform, versions, arch } from 'process';
|
||||||
|
import type { Screen } from '@/types';
|
||||||
import {
|
import {
|
||||||
stopKoboldCpp,
|
stopKoboldCpp,
|
||||||
launchKoboldCppWithCustomFrontends,
|
launchKoboldCppWithCustomFrontends,
|
||||||
|
|
@ -25,11 +26,11 @@ import {
|
||||||
get as getConfig,
|
get as getConfig,
|
||||||
set as setConfig,
|
set as setConfig,
|
||||||
getSelectedConfig,
|
getSelectedConfig,
|
||||||
setSelectedConfig,
|
|
||||||
getInstallDir,
|
getInstallDir,
|
||||||
getColorScheme,
|
getColorScheme,
|
||||||
setColorScheme,
|
getEnableSystemTray,
|
||||||
} from '@/main/modules/config';
|
} from '@/main/modules/config';
|
||||||
|
import { createTray, updateTrayState } from '@/main/modules/tray';
|
||||||
import { getConfigDir, openPathHandler, openUrl } from '@/utils/node/path';
|
import { getConfigDir, openPathHandler, openUrl } from '@/utils/node/path';
|
||||||
import { logError } from '@/utils/node/logging';
|
import { logError } from '@/utils/node/logging';
|
||||||
import { stopFrontend as stopSillyTavernFrontend } from '@/main/modules/sillytavern';
|
import { stopFrontend as stopSillyTavernFrontend } from '@/main/modules/sillytavern';
|
||||||
|
|
@ -76,7 +77,6 @@ import {
|
||||||
isUpdateDownloaded,
|
isUpdateDownloaded,
|
||||||
canAutoUpdate,
|
canAutoUpdate,
|
||||||
} from '@/main/modules/autoUpdater';
|
} from '@/main/modules/autoUpdater';
|
||||||
import { getAppVersion } from '@/utils/node/fs';
|
|
||||||
|
|
||||||
export function setupIPCHandlers() {
|
export function setupIPCHandlers() {
|
||||||
const mainWindow = getMainWindow();
|
const mainWindow = getMainWindow();
|
||||||
|
|
@ -102,7 +102,7 @@ export function setupIPCHandlers() {
|
||||||
ipcMain.handle('kobold:getSelectedConfig', () => getSelectedConfig());
|
ipcMain.handle('kobold:getSelectedConfig', () => getSelectedConfig());
|
||||||
|
|
||||||
ipcMain.handle('kobold:setSelectedConfig', (_, configName) =>
|
ipcMain.handle('kobold:setSelectedConfig', (_, configName) =>
|
||||||
setSelectedConfig(configName)
|
setConfig('selectedConfig', configName)
|
||||||
);
|
);
|
||||||
|
|
||||||
ipcMain.handle('kobold:setCurrentVersion', (_, version) =>
|
ipcMain.handle('kobold:setCurrentVersion', (_, version) =>
|
||||||
|
|
@ -162,12 +162,12 @@ export function setupIPCHandlers() {
|
||||||
|
|
||||||
ipcMain.on('config:set', (_, key, value) => setConfig(key, value));
|
ipcMain.on('config:set', (_, key, value) => setConfig(key, value));
|
||||||
|
|
||||||
ipcMain.handle('app:getVersion', () => getAppVersion());
|
ipcMain.handle('app:getVersion', () => app.getVersion());
|
||||||
|
|
||||||
ipcMain.handle('app:getVersionInfo', async () => {
|
ipcMain.handle('app:getVersionInfo', async () => {
|
||||||
const [appVersion, nodeJsSystemVersion, uvVersion, aurPackageVersion] =
|
const [appVersion, nodeJsSystemVersion, uvVersion, aurPackageVersion] =
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
getAppVersion(),
|
app.getVersion(),
|
||||||
getSystemNodeVersion(),
|
getSystemNodeVersion(),
|
||||||
getUvVersion(),
|
getUvVersion(),
|
||||||
getAURVersion(),
|
getAURVersion(),
|
||||||
|
|
@ -222,7 +222,29 @@ export function setupIPCHandlers() {
|
||||||
ipcMain.handle('app:getColorScheme', () => getColorScheme());
|
ipcMain.handle('app:getColorScheme', () => getColorScheme());
|
||||||
|
|
||||||
ipcMain.handle('app:setColorScheme', (_, colorScheme) =>
|
ipcMain.handle('app:setColorScheme', (_, colorScheme) =>
|
||||||
setColorScheme(colorScheme)
|
setConfig('colorScheme', colorScheme)
|
||||||
|
);
|
||||||
|
|
||||||
|
ipcMain.handle('app:getEnableSystemTray', () => getEnableSystemTray());
|
||||||
|
|
||||||
|
ipcMain.handle('app:setEnableSystemTray', async (_, enabled: boolean) => {
|
||||||
|
await setConfig('enableSystemTray', enabled);
|
||||||
|
createTray();
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle(
|
||||||
|
'app:updateTrayState',
|
||||||
|
(
|
||||||
|
_,
|
||||||
|
state: {
|
||||||
|
screen?: Screen | null;
|
||||||
|
model?: string | null;
|
||||||
|
config?: string | null;
|
||||||
|
monitoringEnabled?: boolean;
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
updateTrayState(state);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
ipcMain.handle('app:openExternal', async (_, url) => openUrl(url));
|
ipcMain.handle('app:openExternal', async (_, url) => openUrl(url));
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import { platform, on } from 'process';
|
||||||
import type { ChildProcess } from 'child_process';
|
import type { ChildProcess } from 'child_process';
|
||||||
import yauzl from 'yauzl';
|
import yauzl from 'yauzl';
|
||||||
import { createWriteStream } from 'fs';
|
import { createWriteStream } from 'fs';
|
||||||
|
import { app } from 'electron';
|
||||||
|
|
||||||
import { logError, safeExecute, tryExecute } from '@/utils/node/logging';
|
import { logError, safeExecute, tryExecute } from '@/utils/node/logging';
|
||||||
import { sendKoboldOutput } from './window';
|
import { sendKoboldOutput } from './window';
|
||||||
|
|
@ -21,7 +22,7 @@ import { getInstallDir } from './config';
|
||||||
import { COMFYUI, SERVER_READY_SIGNALS, GITHUB_API } from '@/constants';
|
import { COMFYUI, SERVER_READY_SIGNALS, GITHUB_API } from '@/constants';
|
||||||
import { terminateProcess } from '@/utils/node/process';
|
import { terminateProcess } from '@/utils/node/process';
|
||||||
import { parseKoboldConfig } from '@/utils/node/kobold';
|
import { parseKoboldConfig } from '@/utils/node/kobold';
|
||||||
import { getAppVersion, ensureDir } from '@/utils/node/fs';
|
import { ensureDir } from '@/utils/node/fs';
|
||||||
import { detectGPU } from './hardware';
|
import { detectGPU } from './hardware';
|
||||||
import { getUvEnvironment } from './dependencies';
|
import { getUvEnvironment } from './dependencies';
|
||||||
|
|
||||||
|
|
@ -559,7 +560,7 @@ export async function startFrontend(args: string[]) {
|
||||||
stdio: 'pipe',
|
stdio: 'pipe',
|
||||||
});
|
});
|
||||||
|
|
||||||
const version = await getAppVersion();
|
const version = await app.getVersion();
|
||||||
sendKoboldOutput(`ComfyUI started via Gerbil v${version}`);
|
sendKoboldOutput(`ComfyUI started via Gerbil v${version}`);
|
||||||
|
|
||||||
if (comfyUIProcess.stdout) {
|
if (comfyUIProcess.stdout) {
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ interface AppConfig {
|
||||||
dismissedUpdates?: DismissedUpdate[];
|
dismissedUpdates?: DismissedUpdate[];
|
||||||
zoomLevel?: number;
|
zoomLevel?: number;
|
||||||
notepad?: SavedNotepadState;
|
notepad?: SavedNotepadState;
|
||||||
|
enableSystemTray?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
let config: AppConfig = {};
|
let config: AppConfig = {};
|
||||||
|
|
@ -98,18 +99,8 @@ export async function setCurrentKoboldBinary(binaryPath: string) {
|
||||||
|
|
||||||
export const getSelectedConfig = () => config.selectedConfig;
|
export const getSelectedConfig = () => config.selectedConfig;
|
||||||
|
|
||||||
export async function setSelectedConfig(configName: string) {
|
|
||||||
config.selectedConfig = configName;
|
|
||||||
await saveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getColorScheme = () => config.colorScheme || 'auto';
|
export const getColorScheme = () => config.colorScheme || 'auto';
|
||||||
|
|
||||||
export async function setColorScheme(colorScheme: MantineColorScheme) {
|
|
||||||
config.colorScheme = colorScheme;
|
|
||||||
await saveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getBackgroundColor() {
|
export function getBackgroundColor() {
|
||||||
const colorScheme = getColorScheme();
|
const colorScheme = getColorScheme();
|
||||||
|
|
||||||
|
|
@ -124,42 +115,4 @@ export function getBackgroundColor() {
|
||||||
|
|
||||||
export const getWindowBounds = () => config.windowBounds;
|
export const getWindowBounds = () => config.windowBounds;
|
||||||
|
|
||||||
export async function setWindowBounds(bounds: WindowBounds) {
|
export const getEnableSystemTray = () => config.enableSystemTray ?? false;
|
||||||
config.windowBounds = bounds;
|
|
||||||
await saveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getFrontendPreference = () => config.frontendPreference;
|
|
||||||
|
|
||||||
export async function setFrontendPreference(preference: FrontendPreference) {
|
|
||||||
config.frontendPreference = preference;
|
|
||||||
await saveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getHasSeenWelcome = () => config.hasSeenWelcome;
|
|
||||||
|
|
||||||
export async function setHasSeenWelcome(hasSeenWelcome: boolean) {
|
|
||||||
config.hasSeenWelcome = hasSeenWelcome;
|
|
||||||
await saveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getSkipEjectConfirmation = () => config.skipEjectConfirmation;
|
|
||||||
|
|
||||||
export async function setSkipEjectConfirmation(skipEjectConfirmation: boolean) {
|
|
||||||
config.skipEjectConfirmation = skipEjectConfirmation;
|
|
||||||
await saveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getDismissedUpdates = () => config.dismissedUpdates || [];
|
|
||||||
|
|
||||||
export async function setDismissedUpdates(dismissedUpdates: DismissedUpdate[]) {
|
|
||||||
config.dismissedUpdates = dismissedUpdates;
|
|
||||||
await saveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getZoomLevel = () => config.zoomLevel;
|
|
||||||
|
|
||||||
export async function setZoomLevel(zoomLevel: number) {
|
|
||||||
config.zoomLevel = zoomLevel;
|
|
||||||
await saveConfig();
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import { platform, env as processEnv } from 'process';
|
||||||
import { execa } from 'execa';
|
import { execa } from 'execa';
|
||||||
import { app } from 'electron';
|
import { app } from 'electron';
|
||||||
|
|
||||||
|
import { PRODUCT_NAME } from '@/constants';
|
||||||
|
|
||||||
async function executeCommand(
|
async function executeCommand(
|
||||||
command: string,
|
command: string,
|
||||||
args: string[],
|
args: string[],
|
||||||
|
|
@ -166,7 +168,7 @@ export async function getAURVersion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { stdout } = await execa('pacman', ['-Q', 'gerbil'], {
|
const { stdout } = await execa('pacman', ['-Q', PRODUCT_NAME], {
|
||||||
timeout: 1000,
|
timeout: 1000,
|
||||||
reject: false,
|
reject: false,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { readdir, stat } from 'fs/promises';
|
import { readdir, stat, rm } from 'fs/promises';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { execa } from 'execa';
|
import { execa } from 'execa';
|
||||||
|
|
||||||
|
|
@ -159,7 +159,6 @@ export async function deleteRelease(binaryPath: string) {
|
||||||
const releaseDir = binaryPath.split(/[/\\]/).slice(0, -1).join('/');
|
const releaseDir = binaryPath.split(/[/\\]/).slice(0, -1).join('/');
|
||||||
|
|
||||||
if (await pathExists(releaseDir)) {
|
if (await pathExists(releaseDir)) {
|
||||||
const { rm } = await import('fs/promises');
|
|
||||||
await rm(releaseDir, { recursive: true, force: true });
|
await rm(releaseDir, { recursive: true, force: true });
|
||||||
|
|
||||||
clearVersionCache(binaryPath);
|
clearVersionCache(binaryPath);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { spawn } from 'child_process';
|
||||||
import { getGPUData } from '@/utils/node/gpu';
|
import { getGPUData } from '@/utils/node/gpu';
|
||||||
import { detectGPU } from './hardware';
|
import { detectGPU } from './hardware';
|
||||||
import { tryExecute, safeExecute } from '@/utils/node/logging';
|
import { tryExecute, safeExecute } from '@/utils/node/logging';
|
||||||
|
import { isTrayActive, updateMetrics } from './tray';
|
||||||
|
|
||||||
export interface CpuMetrics {
|
export interface CpuMetrics {
|
||||||
usage: number;
|
usage: number;
|
||||||
|
|
@ -53,6 +54,10 @@ let isRunning = false;
|
||||||
const updateFrequency = 1000;
|
const updateFrequency = 1000;
|
||||||
let mainWindow: BrowserWindow | null = null;
|
let mainWindow: BrowserWindow | null = null;
|
||||||
|
|
||||||
|
let latestCpuMetrics: CpuMetrics | null = null;
|
||||||
|
let latestMemoryMetrics: MemoryMetrics | null = null;
|
||||||
|
let latestGpuMetrics: GpuMetrics | null = null;
|
||||||
|
|
||||||
export function startMonitoring(window: BrowserWindow) {
|
export function startMonitoring(window: BrowserWindow) {
|
||||||
if (isRunning) return;
|
if (isRunning) return;
|
||||||
|
|
||||||
|
|
@ -93,6 +98,12 @@ export function stopMonitoring() {
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateTrayWithMetrics() {
|
||||||
|
if (isTrayActive()) {
|
||||||
|
updateMetrics(latestCpuMetrics, latestMemoryMetrics, latestGpuMetrics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function collectAndSendCpuMetrics() {
|
async function collectAndSendCpuMetrics() {
|
||||||
await tryExecute(async () => {
|
await tryExecute(async () => {
|
||||||
const cpuData = await currentLoad();
|
const cpuData = await currentLoad();
|
||||||
|
|
@ -110,6 +121,9 @@ async function collectAndSendCpuMetrics() {
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
latestCpuMetrics = metrics;
|
||||||
|
updateTrayWithMetrics();
|
||||||
|
|
||||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||||
mainWindow.webContents.send('cpu-metrics', metrics);
|
mainWindow.webContents.send('cpu-metrics', metrics);
|
||||||
}
|
}
|
||||||
|
|
@ -127,6 +141,9 @@ async function collectAndSendMemoryMetrics() {
|
||||||
usage: Math.round((usedBytes / totalBytes) * 100),
|
usage: Math.round((usedBytes / totalBytes) * 100),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
latestMemoryMetrics = metrics;
|
||||||
|
updateTrayWithMetrics();
|
||||||
|
|
||||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||||
mainWindow.webContents.send('memory-metrics', metrics);
|
mainWindow.webContents.send('memory-metrics', metrics);
|
||||||
}
|
}
|
||||||
|
|
@ -150,6 +167,9 @@ async function collectAndSendGpuMetrics() {
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
latestGpuMetrics = metrics;
|
||||||
|
updateTrayWithMetrics();
|
||||||
|
|
||||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||||
mainWindow.webContents.send('gpu-metrics', metrics);
|
mainWindow.webContents.send('gpu-metrics', metrics);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { spawn } from 'child_process';
|
import { spawn } from 'child_process';
|
||||||
import type { ChildProcess } from 'child_process';
|
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { on } from 'process';
|
import { on } from 'process';
|
||||||
|
import { app } from 'electron';
|
||||||
|
import type { ChildProcess } from 'child_process';
|
||||||
|
|
||||||
import { logError } from '@/utils/node/logging';
|
import { logError } from '@/utils/node/logging';
|
||||||
import { sendKoboldOutput } from './window';
|
import { sendKoboldOutput } from './window';
|
||||||
|
|
@ -9,7 +10,6 @@ import { getInstallDir } from './config';
|
||||||
import { OPENWEBUI, SERVER_READY_SIGNALS } from '@/constants';
|
import { OPENWEBUI, SERVER_READY_SIGNALS } from '@/constants';
|
||||||
import { terminateProcess } from '@/utils/node/process';
|
import { terminateProcess } from '@/utils/node/process';
|
||||||
import { parseKoboldConfig } from '@/utils/node/kobold';
|
import { parseKoboldConfig } from '@/utils/node/kobold';
|
||||||
import { getAppVersion } from '@/utils/node/fs';
|
|
||||||
import { getUvEnvironment } from './dependencies';
|
import { getUvEnvironment } from './dependencies';
|
||||||
|
|
||||||
let openWebUIProcess: ChildProcess | null = null;
|
let openWebUIProcess: ChildProcess | null = null;
|
||||||
|
|
@ -69,7 +69,10 @@ export async function startFrontend(args: string[]) {
|
||||||
isImageMode,
|
isImageMode,
|
||||||
} = parseKoboldConfig(args);
|
} = parseKoboldConfig(args);
|
||||||
|
|
||||||
const [, appVersion] = await Promise.all([stopFrontend(), getAppVersion()]);
|
const [, appVersion] = await Promise.all([
|
||||||
|
stopFrontend(),
|
||||||
|
app.getVersion(),
|
||||||
|
]);
|
||||||
|
|
||||||
sendKoboldOutput(
|
sendKoboldOutput(
|
||||||
`Preparing Open WebUI to connect at ${koboldHost}:${koboldPort}${isImageMode ? ' (with image generation)' : ''}...`
|
`Preparing Open WebUI to connect at ${koboldHost}:${koboldPort}${isImageMode ? ' (with image generation)' : ''}...`
|
||||||
|
|
|
||||||
249
src/main/modules/tray.ts
Normal file
249
src/main/modules/tray.ts
Normal file
|
|
@ -0,0 +1,249 @@
|
||||||
|
import {
|
||||||
|
app,
|
||||||
|
Tray,
|
||||||
|
Menu,
|
||||||
|
nativeImage,
|
||||||
|
MenuItemConstructorOptions,
|
||||||
|
} from 'electron';
|
||||||
|
import { join } from 'path';
|
||||||
|
import { resourcesPath } from 'process';
|
||||||
|
import { getEnableSystemTray } from './config';
|
||||||
|
import { getMainWindow } from './window';
|
||||||
|
import type { CpuMetrics, MemoryMetrics, GpuMetrics } from './monitoring';
|
||||||
|
import type { Screen } from '@/types';
|
||||||
|
import { PRODUCT_NAME } from '@/constants';
|
||||||
|
|
||||||
|
let tray: Tray | null = null;
|
||||||
|
let currentMetrics: {
|
||||||
|
cpu: CpuMetrics | null;
|
||||||
|
memory: MemoryMetrics | null;
|
||||||
|
gpu: GpuMetrics | null;
|
||||||
|
} = {
|
||||||
|
cpu: null,
|
||||||
|
memory: null,
|
||||||
|
gpu: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
interface TrayAppState {
|
||||||
|
currentScreen: Screen | null;
|
||||||
|
isLaunched: boolean;
|
||||||
|
currentModel: string | null;
|
||||||
|
currentConfig: string | null;
|
||||||
|
monitoringEnabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const appState: TrayAppState = {
|
||||||
|
currentScreen: null,
|
||||||
|
isLaunched: false,
|
||||||
|
currentModel: null,
|
||||||
|
currentConfig: null,
|
||||||
|
monitoringEnabled: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function updateTrayState(state: {
|
||||||
|
screen?: Screen | null;
|
||||||
|
model?: string | null;
|
||||||
|
config?: string | null;
|
||||||
|
monitoringEnabled?: boolean;
|
||||||
|
}) {
|
||||||
|
if (state.screen !== undefined) {
|
||||||
|
appState.currentScreen = state.screen;
|
||||||
|
appState.isLaunched = state.screen === 'interface';
|
||||||
|
}
|
||||||
|
if (state.model !== undefined) {
|
||||||
|
appState.currentModel = state.model;
|
||||||
|
}
|
||||||
|
if (state.config !== undefined) {
|
||||||
|
appState.currentConfig = state.config;
|
||||||
|
}
|
||||||
|
if (state.monitoringEnabled !== undefined) {
|
||||||
|
appState.monitoringEnabled = state.monitoringEnabled;
|
||||||
|
}
|
||||||
|
updateTrayMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateMetrics(
|
||||||
|
cpu: CpuMetrics | null,
|
||||||
|
memory: MemoryMetrics | null,
|
||||||
|
gpu: GpuMetrics | null
|
||||||
|
) {
|
||||||
|
currentMetrics = { cpu, memory, gpu };
|
||||||
|
updateTrayTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildTooltipText() {
|
||||||
|
const parts: string[] = [];
|
||||||
|
|
||||||
|
if (
|
||||||
|
appState.monitoringEnabled &&
|
||||||
|
currentMetrics.cpu &&
|
||||||
|
currentMetrics.memory
|
||||||
|
) {
|
||||||
|
const metrics: string[] = [];
|
||||||
|
|
||||||
|
const cpuText = `CPU: ${currentMetrics.cpu.usage}%${currentMetrics.cpu.temperature ? ` • ${currentMetrics.cpu.temperature}°C` : ''}`;
|
||||||
|
metrics.push(cpuText);
|
||||||
|
|
||||||
|
const ramText = `RAM: ${currentMetrics.memory.used.toFixed(2)} GB / ${currentMetrics.memory.total.toFixed(2)} GB (${currentMetrics.memory.usage}%)`;
|
||||||
|
metrics.push(ramText);
|
||||||
|
|
||||||
|
if (currentMetrics.gpu?.gpus) {
|
||||||
|
currentMetrics.gpu.gpus.forEach((gpu, index) => {
|
||||||
|
const gpuLabel =
|
||||||
|
currentMetrics.gpu!.gpus.length > 1 ? `GPU ${index + 1}` : 'GPU';
|
||||||
|
const gpuText = `${gpuLabel}: ${gpu.usage}%${gpu.temperature ? ` • ${gpu.temperature}°C` : ''}`;
|
||||||
|
metrics.push(gpuText);
|
||||||
|
|
||||||
|
const vramLabel =
|
||||||
|
currentMetrics.gpu!.gpus.length > 1 ? `VRAM ${index + 1}` : 'VRAM';
|
||||||
|
const vramText = `${vramLabel}: ${gpu.memoryUsed.toFixed(2)} GB / ${gpu.memoryTotal.toFixed(2)} GB (${gpu.memoryUsage}%)`;
|
||||||
|
metrics.push(vramText);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
parts.push(...metrics);
|
||||||
|
} else {
|
||||||
|
parts.push(PRODUCT_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTrayTooltip() {
|
||||||
|
if (tray) {
|
||||||
|
tray.setToolTip(buildTooltipText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildContextMenu() {
|
||||||
|
const mainWindow = getMainWindow();
|
||||||
|
const isVisible = mainWindow.isVisible();
|
||||||
|
|
||||||
|
const menuTemplate: MenuItemConstructorOptions[] = [];
|
||||||
|
|
||||||
|
if (isVisible) {
|
||||||
|
menuTemplate.push({
|
||||||
|
label: 'Hide Gerbil',
|
||||||
|
click: () => {
|
||||||
|
mainWindow.hide();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
menuTemplate.push({
|
||||||
|
label: 'Show Gerbil',
|
||||||
|
click: () => {
|
||||||
|
mainWindow.show();
|
||||||
|
mainWindow.focus();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
menuTemplate.push({ type: 'separator' });
|
||||||
|
|
||||||
|
if (appState.currentScreen === 'launch' && !appState.isLaunched) {
|
||||||
|
menuTemplate.push({
|
||||||
|
label: 'Launch with Current Config',
|
||||||
|
enabled: !!appState.currentConfig,
|
||||||
|
click: () => {
|
||||||
|
const mainWindow = getMainWindow();
|
||||||
|
mainWindow.webContents.send('tray:launch');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (appState.isLaunched && appState.currentScreen === 'interface') {
|
||||||
|
if (appState.currentModel) {
|
||||||
|
menuTemplate.push({
|
||||||
|
label: `Running: ${appState.currentModel}`,
|
||||||
|
enabled: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
menuTemplate.push({
|
||||||
|
label: 'Eject Model',
|
||||||
|
click: () => {
|
||||||
|
const mainWindow = getMainWindow();
|
||||||
|
mainWindow.webContents.send('tray:eject');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
menuTemplate.push(
|
||||||
|
{ type: 'separator' },
|
||||||
|
{
|
||||||
|
label: 'Quit',
|
||||||
|
click: () => {
|
||||||
|
app.quit();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return Menu.buildFromTemplate(menuTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createTray() {
|
||||||
|
const isEnabled = getEnableSystemTray();
|
||||||
|
|
||||||
|
if (!isEnabled) {
|
||||||
|
destroyTray();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tray) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let iconPath: string;
|
||||||
|
if (app.isPackaged) {
|
||||||
|
iconPath = join(resourcesPath, 'assets', 'icon.png');
|
||||||
|
} else {
|
||||||
|
iconPath = join(__dirname, '../../src/assets/icon.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
const icon = nativeImage.createFromPath(iconPath);
|
||||||
|
|
||||||
|
if (icon.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tray = new Tray(icon.resize({ width: 16, height: 16 }));
|
||||||
|
|
||||||
|
updateTrayTooltip();
|
||||||
|
tray.setContextMenu(buildContextMenu());
|
||||||
|
|
||||||
|
tray.on('click', () => {
|
||||||
|
const mainWindow = getMainWindow();
|
||||||
|
if (mainWindow.isVisible()) {
|
||||||
|
mainWindow.hide();
|
||||||
|
} else {
|
||||||
|
mainWindow.show();
|
||||||
|
mainWindow.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const mainWindow = getMainWindow();
|
||||||
|
mainWindow.on('show', () => {
|
||||||
|
if (tray) {
|
||||||
|
tray.setContextMenu(buildContextMenu());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mainWindow.on('hide', () => {
|
||||||
|
if (tray) {
|
||||||
|
tray.setContextMenu(buildContextMenu());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function destroyTray() {
|
||||||
|
if (tray) {
|
||||||
|
tray.destroy();
|
||||||
|
tray = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateTrayMenu() {
|
||||||
|
if (tray) {
|
||||||
|
tray.setContextMenu(buildContextMenu());
|
||||||
|
updateTrayTooltip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const isTrayActive = () => tray !== null;
|
||||||
|
|
@ -10,7 +10,9 @@ import {
|
||||||
getWindowBounds,
|
getWindowBounds,
|
||||||
setWindowBounds,
|
setWindowBounds,
|
||||||
WindowBounds,
|
WindowBounds,
|
||||||
|
getEnableSystemTray,
|
||||||
} from './config';
|
} from './config';
|
||||||
|
import { isTrayActive } from './tray';
|
||||||
|
|
||||||
let mainWindow: BrowserWindow | null = null;
|
let mainWindow: BrowserWindow | null = null;
|
||||||
|
|
||||||
|
|
@ -146,9 +148,14 @@ export function createMainWindow() {
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
mainWindow.on('close', () => {
|
mainWindow.on('close', (event) => {
|
||||||
|
if (getEnableSystemTray() && isTrayActive()) {
|
||||||
|
event.preventDefault();
|
||||||
|
mainWindow?.hide();
|
||||||
|
} else {
|
||||||
saveBounds();
|
saveBounds();
|
||||||
app.quit();
|
app.quit();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setupContextMenu(mainWindow);
|
setupContextMenu(mainWindow);
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,24 @@ const appAPI: AppAPI = {
|
||||||
getColorScheme: () => ipcRenderer.invoke('app:getColorScheme'),
|
getColorScheme: () => ipcRenderer.invoke('app:getColorScheme'),
|
||||||
setColorScheme: (colorScheme) =>
|
setColorScheme: (colorScheme) =>
|
||||||
ipcRenderer.invoke('app:setColorScheme', colorScheme),
|
ipcRenderer.invoke('app:setColorScheme', colorScheme),
|
||||||
|
getEnableSystemTray: () => ipcRenderer.invoke('app:getEnableSystemTray'),
|
||||||
|
setEnableSystemTray: (enabled) =>
|
||||||
|
ipcRenderer.invoke('app:setEnableSystemTray', enabled),
|
||||||
|
updateTrayState: (state) => ipcRenderer.invoke('app:updateTrayState', state),
|
||||||
|
onTrayLaunch: (callback) => {
|
||||||
|
const handler = () => callback();
|
||||||
|
ipcRenderer.on('tray:launch', handler);
|
||||||
|
return () => {
|
||||||
|
ipcRenderer.removeListener('tray:launch', handler);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onTrayEject: (callback) => {
|
||||||
|
const handler = () => callback();
|
||||||
|
ipcRenderer.on('tray:eject', handler);
|
||||||
|
return () => {
|
||||||
|
ipcRenderer.removeListener('tray:eject', handler);
|
||||||
|
};
|
||||||
|
},
|
||||||
openExternal: (url) => ipcRenderer.invoke('app:openExternal', url),
|
openExternal: (url) => ipcRenderer.invoke('app:openExternal', url),
|
||||||
openPerformanceManager: () =>
|
openPerformanceManager: () =>
|
||||||
ipcRenderer.invoke('app:openPerformanceManager'),
|
ipcRenderer.invoke('app:openPerformanceManager'),
|
||||||
|
|
|
||||||
12
src/types/electron.d.ts
vendored
12
src/types/electron.d.ts
vendored
|
|
@ -5,7 +5,7 @@ import type {
|
||||||
GPUMemoryInfo,
|
GPUMemoryInfo,
|
||||||
SystemMemoryInfo,
|
SystemMemoryInfo,
|
||||||
} from '@/types/hardware';
|
} from '@/types/hardware';
|
||||||
import type { BackendOption, BackendSupport } from '@/types';
|
import type { BackendOption, BackendSupport, Screen } from '@/types';
|
||||||
import type { MantineColorScheme } from '@mantine/core';
|
import type { MantineColorScheme } from '@mantine/core';
|
||||||
import type {
|
import type {
|
||||||
CpuMetrics,
|
CpuMetrics,
|
||||||
|
|
@ -175,6 +175,16 @@ export interface AppAPI {
|
||||||
setZoomLevel: (level: number) => Promise<void>;
|
setZoomLevel: (level: number) => Promise<void>;
|
||||||
getColorScheme: () => Promise<MantineColorScheme>;
|
getColorScheme: () => Promise<MantineColorScheme>;
|
||||||
setColorScheme: (colorScheme: MantineColorScheme) => Promise<void>;
|
setColorScheme: (colorScheme: MantineColorScheme) => Promise<void>;
|
||||||
|
getEnableSystemTray: () => Promise<boolean>;
|
||||||
|
setEnableSystemTray: (enabled: boolean) => Promise<void>;
|
||||||
|
updateTrayState: (state: {
|
||||||
|
screen?: Screen | null;
|
||||||
|
model?: string | null;
|
||||||
|
config?: string | null;
|
||||||
|
monitoringEnabled?: boolean;
|
||||||
|
}) => Promise<void>;
|
||||||
|
onTrayLaunch: (callback: () => void) => () => void;
|
||||||
|
onTrayEject: (callback: () => void) => () => void;
|
||||||
openExternal: (url: string) => Promise<void>;
|
openExternal: (url: string) => Promise<void>;
|
||||||
openPerformanceManager: () => Promise<{
|
openPerformanceManager: () => Promise<{
|
||||||
success: boolean;
|
success: boolean;
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,3 @@ export const ensureDir = async (path: string) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAppVersion = async () => {
|
|
||||||
const { app } = await import('electron');
|
|
||||||
return app.getVersion();
|
|
||||||
};
|
|
||||||
|
|
|
||||||
348
yarn.lock
348
yarn.lock
|
|
@ -315,15 +315,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0, @codemirror/view@npm:^6.35.0, @codemirror/view@npm:^6.38.3":
|
"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0, @codemirror/view@npm:^6.35.0, @codemirror/view@npm:^6.38.4":
|
||||||
version: 6.38.3
|
version: 6.38.4
|
||||||
resolution: "@codemirror/view@npm:6.38.3"
|
resolution: "@codemirror/view@npm:6.38.4"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@codemirror/state": "npm:^6.5.0"
|
"@codemirror/state": "npm:^6.5.0"
|
||||||
crelt: "npm:^1.0.6"
|
crelt: "npm:^1.0.6"
|
||||||
style-mod: "npm:^4.1.0"
|
style-mod: "npm:^4.1.0"
|
||||||
w3c-keyname: "npm:^2.2.4"
|
w3c-keyname: "npm:^2.2.4"
|
||||||
checksum: 10c0/70c9ec6d6a6528d64613c922165cc156f564435be50767167785fa97cb1be29d1d4c95a550405ce8144bc4147138ca463c6f1b94afa6b42b45e4f9cbe9045ec5
|
checksum: 10c0/8133e7d723f5ca82449e866cffdd267f72c5f924b5a88bdbc1ae29ca3e3274c8c5695342c82da8eb5b0509688ef8a0cfc6d517352a5329cfc3fed2cbbd504ce4
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -334,14 +334,14 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@dabh/diagnostics@npm:^2.0.2":
|
"@dabh/diagnostics@npm:^2.0.8":
|
||||||
version: 2.0.3
|
version: 2.0.8
|
||||||
resolution: "@dabh/diagnostics@npm:2.0.3"
|
resolution: "@dabh/diagnostics@npm:2.0.8"
|
||||||
dependencies:
|
dependencies:
|
||||||
colorspace: "npm:1.1.x"
|
"@so-ric/colorspace": "npm:^1.1.6"
|
||||||
enabled: "npm:2.0.x"
|
enabled: "npm:2.0.x"
|
||||||
kuler: "npm:^2.0.0"
|
kuler: "npm:^2.0.0"
|
||||||
checksum: 10c0/a5133df8492802465ed01f2f0a5784585241a1030c362d54a602ed1839816d6c93d71dde05cf2ddb4fd0796238c19774406bd62fa2564b637907b495f52425fe
|
checksum: 10c0/64701c272f7de02800039fea99796507670fe5f67d4eb7718599351ec156936efd123fcab7ee18f9d7874939caaacc08e7c7a6bb05ff8cda6d930ad041cc555c
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -1099,10 +1099,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rolldown/pluginutils@npm:1.0.0-beta.35":
|
"@rolldown/pluginutils@npm:1.0.0-beta.38":
|
||||||
version: 1.0.0-beta.35
|
version: 1.0.0-beta.38
|
||||||
resolution: "@rolldown/pluginutils@npm:1.0.0-beta.35"
|
resolution: "@rolldown/pluginutils@npm:1.0.0-beta.38"
|
||||||
checksum: 10c0/feb6ab8f77ef2bde675099409c3ccd6a168f35a3c3e88482df3ca42494260fd42befe36e8e90ce358847a12aaab94cd8fe7069cf1e905edf91eb411d933906d9
|
checksum: 10c0/8353ec2528349f79e27d1a3193806725b85830da334e935cbb606d88c1177c58ea6519c578e4e93e5f677f5b22aecb8738894dbed14603e14b6bffe3facf1002
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -1288,6 +1288,16 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@so-ric/colorspace@npm:^1.1.6":
|
||||||
|
version: 1.1.6
|
||||||
|
resolution: "@so-ric/colorspace@npm:1.1.6"
|
||||||
|
dependencies:
|
||||||
|
color: "npm:^5.0.2"
|
||||||
|
text-hex: "npm:1.0.x"
|
||||||
|
checksum: 10c0/f3ad26afefbb8d6101ea7c385cd5f402d4291c2ffc9cabe37030d5fdb8bda980ee534a0d7c250f8233fc3a59b99272410177cd98b219f6b3770f91a0fdb6eb3e
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@szmarczak/http-timer@npm:^4.0.5":
|
"@szmarczak/http-timer@npm:^4.0.5":
|
||||||
version: 4.0.6
|
version: 4.0.6
|
||||||
resolution: "@szmarczak/http-timer@npm:4.0.6"
|
resolution: "@szmarczak/http-timer@npm:4.0.6"
|
||||||
|
|
@ -1419,12 +1429,12 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/node@npm:*, @types/node@npm:^24.5.2":
|
"@types/node@npm:*":
|
||||||
version: 24.5.2
|
version: 24.6.0
|
||||||
resolution: "@types/node@npm:24.5.2"
|
resolution: "@types/node@npm:24.6.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: "npm:~7.12.0"
|
undici-types: "npm:~7.13.0"
|
||||||
checksum: 10c0/96baaca6564d39c6f7f6eddd73ce41e2a7594ef37225cd52df3be36fad31712af8ae178387a72d0b80f2e2799e7fd30c014bc0ae9eb9f962d9079b691be00c48
|
checksum: 10c0/06f1aa1b5d9a8c26285b34c25aee554f31a1dc0b39627cc14e7c1c6967e75a47ab9f409eee14796cbcc004ae4059fa884cb6092ecfb368c9656d16686d7cc9d8
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -1437,6 +1447,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/node@npm:^24.6.1":
|
||||||
|
version: 24.6.1
|
||||||
|
resolution: "@types/node@npm:24.6.1"
|
||||||
|
dependencies:
|
||||||
|
undici-types: "npm:~7.13.0"
|
||||||
|
checksum: 10c0/f2f8aea441d72139345cfa2e392af51bc27d12eb5f74b9b4d202046a2e82ab70d6da89c46a2ac7feea98854c2919e53070869d4af9d448e173a77249fcb7bca3
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/plist@npm:^3.0.1":
|
"@types/plist@npm:^3.0.1":
|
||||||
version: 3.0.5
|
version: 3.0.5
|
||||||
resolution: "@types/plist@npm:3.0.5"
|
resolution: "@types/plist@npm:3.0.5"
|
||||||
|
|
@ -1456,12 +1475,12 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/react@npm:^19.1.14":
|
"@types/react@npm:^19.1.16":
|
||||||
version: 19.1.14
|
version: 19.1.16
|
||||||
resolution: "@types/react@npm:19.1.14"
|
resolution: "@types/react@npm:19.1.16"
|
||||||
dependencies:
|
dependencies:
|
||||||
csstype: "npm:^3.0.2"
|
csstype: "npm:^3.0.2"
|
||||||
checksum: 10c0/0d1629e065413be79c949f011845836e7f515c8f97dbfef057719be2f312b404405d2d064cb28e03363c62c153c100e84268c09dd9aeda488858d45033b520f0
|
checksum: 10c0/3d781f715f15f308b601d74142fae77c65679c318a3bb0a319df898f39095e738ba7ed7061cec971b19b6d33969ef9cd50fec92b034024ef3fcc25bb9a2eb3d0
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -1497,106 +1516,106 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin@npm:^8.44.1":
|
"@typescript-eslint/eslint-plugin@npm:^8.45.0":
|
||||||
version: 8.44.1
|
version: 8.45.0
|
||||||
resolution: "@typescript-eslint/eslint-plugin@npm:8.44.1"
|
resolution: "@typescript-eslint/eslint-plugin@npm:8.45.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@eslint-community/regexpp": "npm:^4.10.0"
|
"@eslint-community/regexpp": "npm:^4.10.0"
|
||||||
"@typescript-eslint/scope-manager": "npm:8.44.1"
|
"@typescript-eslint/scope-manager": "npm:8.45.0"
|
||||||
"@typescript-eslint/type-utils": "npm:8.44.1"
|
"@typescript-eslint/type-utils": "npm:8.45.0"
|
||||||
"@typescript-eslint/utils": "npm:8.44.1"
|
"@typescript-eslint/utils": "npm:8.45.0"
|
||||||
"@typescript-eslint/visitor-keys": "npm:8.44.1"
|
"@typescript-eslint/visitor-keys": "npm:8.45.0"
|
||||||
graphemer: "npm:^1.4.0"
|
graphemer: "npm:^1.4.0"
|
||||||
ignore: "npm:^7.0.0"
|
ignore: "npm:^7.0.0"
|
||||||
natural-compare: "npm:^1.4.0"
|
natural-compare: "npm:^1.4.0"
|
||||||
ts-api-utils: "npm:^2.1.0"
|
ts-api-utils: "npm:^2.1.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
"@typescript-eslint/parser": ^8.44.1
|
"@typescript-eslint/parser": ^8.45.0
|
||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
typescript: ">=4.8.4 <6.0.0"
|
typescript: ">=4.8.4 <6.0.0"
|
||||||
checksum: 10c0/86d17444c38992a5dc0e45c107a2c2545eb26a1314c2475e7518e4b7645781be4449ec49463667d63aaffaa002e2edacbd2098104cc83e8399e3dd6e0fb6ed51
|
checksum: 10c0/0c60a0e5d07fa8618348db38b5a81e66143d528e1b3cdb5678bbc6c60590cd559b27c98c36f5663230fc4cf6920dff2cd604de30b58df26a37fcfcc5dc1dbd45
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/parser@npm:^8.44.1":
|
"@typescript-eslint/parser@npm:^8.45.0":
|
||||||
version: 8.44.1
|
version: 8.45.0
|
||||||
resolution: "@typescript-eslint/parser@npm:8.44.1"
|
resolution: "@typescript-eslint/parser@npm:8.45.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/scope-manager": "npm:8.44.1"
|
"@typescript-eslint/scope-manager": "npm:8.45.0"
|
||||||
"@typescript-eslint/types": "npm:8.44.1"
|
"@typescript-eslint/types": "npm:8.45.0"
|
||||||
"@typescript-eslint/typescript-estree": "npm:8.44.1"
|
"@typescript-eslint/typescript-estree": "npm:8.45.0"
|
||||||
"@typescript-eslint/visitor-keys": "npm:8.44.1"
|
"@typescript-eslint/visitor-keys": "npm:8.45.0"
|
||||||
debug: "npm:^4.3.4"
|
debug: "npm:^4.3.4"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
typescript: ">=4.8.4 <6.0.0"
|
typescript: ">=4.8.4 <6.0.0"
|
||||||
checksum: 10c0/278d7f6a8a686fade0cff372faabb5e114f98ce4032bd991e8905622c720f3a4867b99f7a07897aa2e26311efd8cbb84669059ab57ac99c644b9fbae7564b251
|
checksum: 10c0/8b419bcf795b112a39fcac05dcf147835059345b6399035ffa3f76a9d8e320f3fac79cae2fe4320dcda83fa059b017ca7626a7b4e3da08a614415c8867d169b8
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/project-service@npm:8.44.1":
|
"@typescript-eslint/project-service@npm:8.45.0":
|
||||||
version: 8.44.1
|
version: 8.45.0
|
||||||
resolution: "@typescript-eslint/project-service@npm:8.44.1"
|
resolution: "@typescript-eslint/project-service@npm:8.45.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/tsconfig-utils": "npm:^8.44.1"
|
"@typescript-eslint/tsconfig-utils": "npm:^8.45.0"
|
||||||
"@typescript-eslint/types": "npm:^8.44.1"
|
"@typescript-eslint/types": "npm:^8.45.0"
|
||||||
debug: "npm:^4.3.4"
|
debug: "npm:^4.3.4"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: ">=4.8.4 <6.0.0"
|
typescript: ">=4.8.4 <6.0.0"
|
||||||
checksum: 10c0/2caaa94832574658f1b451d94a319fcd476ad34171e6dff6607da9a5f91387011206487b7743fc71c9c91099632871fa6d209783cbc0a7cb3bac5cbf9d36cdae
|
checksum: 10c0/98af065a1a3ed9d3d1eb265e09d3e9c2ae676d500a8c1d764f5609fe2c1b86749516b709804eb814fae688be7809d11748b9ae691d43c28da51dac390ca81fa9
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager@npm:8.44.1":
|
"@typescript-eslint/scope-manager@npm:8.45.0":
|
||||||
version: 8.44.1
|
version: 8.45.0
|
||||||
resolution: "@typescript-eslint/scope-manager@npm:8.44.1"
|
resolution: "@typescript-eslint/scope-manager@npm:8.45.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types": "npm:8.44.1"
|
"@typescript-eslint/types": "npm:8.45.0"
|
||||||
"@typescript-eslint/visitor-keys": "npm:8.44.1"
|
"@typescript-eslint/visitor-keys": "npm:8.45.0"
|
||||||
checksum: 10c0/a6f3b2d9fbda037327574bb2a7d3831cc100122fe660545a8220e4eed0ee36e42262ce78cc7438dd155100d0abca38edd9e6941e29abe6f8ba7f935223059b89
|
checksum: 10c0/54cd36206f6b4fc8e1e48576ed01e0d6ab20c2a9c4c7d90d5cc3a2d317dd8a13abe148ffecf471b16f1224aba5749e0905472745626bef9ae5bed771776f4abe
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/tsconfig-utils@npm:8.44.1, @typescript-eslint/tsconfig-utils@npm:^8.44.1":
|
"@typescript-eslint/tsconfig-utils@npm:8.45.0, @typescript-eslint/tsconfig-utils@npm:^8.45.0":
|
||||||
version: 8.44.1
|
version: 8.45.0
|
||||||
resolution: "@typescript-eslint/tsconfig-utils@npm:8.44.1"
|
resolution: "@typescript-eslint/tsconfig-utils@npm:8.45.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: ">=4.8.4 <6.0.0"
|
typescript: ">=4.8.4 <6.0.0"
|
||||||
checksum: 10c0/05fee17cdb38729f82bdfff3bf2844435f5f8e4e55cdaf1bbff72c410ab98a4f9e166011f1eda01f715053d4bc9eb2d8d6c05e9e7114cc08946c4c81785367a0
|
checksum: 10c0/227a9b7a5baaf35466fd369992cb933192515df1156ddf22f438deb344c2523695208e1036f5590b20603f31724de75a47fe0ee84e2fd4c8e9f3606f23f68112
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/type-utils@npm:8.44.1":
|
"@typescript-eslint/type-utils@npm:8.45.0":
|
||||||
version: 8.44.1
|
version: 8.45.0
|
||||||
resolution: "@typescript-eslint/type-utils@npm:8.44.1"
|
resolution: "@typescript-eslint/type-utils@npm:8.45.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types": "npm:8.44.1"
|
"@typescript-eslint/types": "npm:8.45.0"
|
||||||
"@typescript-eslint/typescript-estree": "npm:8.44.1"
|
"@typescript-eslint/typescript-estree": "npm:8.45.0"
|
||||||
"@typescript-eslint/utils": "npm:8.44.1"
|
"@typescript-eslint/utils": "npm:8.45.0"
|
||||||
debug: "npm:^4.3.4"
|
debug: "npm:^4.3.4"
|
||||||
ts-api-utils: "npm:^2.1.0"
|
ts-api-utils: "npm:^2.1.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
typescript: ">=4.8.4 <6.0.0"
|
typescript: ">=4.8.4 <6.0.0"
|
||||||
checksum: 10c0/f17b9ae60327b9187354499d67c2667811ca2b09d436cf6c13b89ba6eaceabd5695f87644a8cb4dc93da5e4188612a6bc7b07b1b022ad75ca360ff2608a64511
|
checksum: 10c0/ce0f4c209c2418ebeb65e7de053499fb68bf6000bdd71068594fdb8c8ac3dbbd62935a3cea233989491f7da3ef5db87e7efd2910133c6abf6d0cbf57248f6442
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/types@npm:8.44.1, @typescript-eslint/types@npm:^8.44.1":
|
"@typescript-eslint/types@npm:8.45.0, @typescript-eslint/types@npm:^8.45.0":
|
||||||
version: 8.44.1
|
version: 8.45.0
|
||||||
resolution: "@typescript-eslint/types@npm:8.44.1"
|
resolution: "@typescript-eslint/types@npm:8.45.0"
|
||||||
checksum: 10c0/cba2d724ac0c7e5a35945aa2f7f8ed96dd5508942e30ec88274dcd2e8fa2c177b0952403c7eb6cacbcc2014224bd36685947d140c093637e3a4e5495c52fbd9f
|
checksum: 10c0/0213a0573c671d13bc91961a2b2e814ec7f6381ff093bce6704017bd96b2fc7fee25906c815cedb32a0601cf5071ca6c7c5f940d087c3b0d3dd7d4bc03478278
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree@npm:8.44.1":
|
"@typescript-eslint/typescript-estree@npm:8.45.0":
|
||||||
version: 8.44.1
|
version: 8.45.0
|
||||||
resolution: "@typescript-eslint/typescript-estree@npm:8.44.1"
|
resolution: "@typescript-eslint/typescript-estree@npm:8.45.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/project-service": "npm:8.44.1"
|
"@typescript-eslint/project-service": "npm:8.45.0"
|
||||||
"@typescript-eslint/tsconfig-utils": "npm:8.44.1"
|
"@typescript-eslint/tsconfig-utils": "npm:8.45.0"
|
||||||
"@typescript-eslint/types": "npm:8.44.1"
|
"@typescript-eslint/types": "npm:8.45.0"
|
||||||
"@typescript-eslint/visitor-keys": "npm:8.44.1"
|
"@typescript-eslint/visitor-keys": "npm:8.45.0"
|
||||||
debug: "npm:^4.3.4"
|
debug: "npm:^4.3.4"
|
||||||
fast-glob: "npm:^3.3.2"
|
fast-glob: "npm:^3.3.2"
|
||||||
is-glob: "npm:^4.0.3"
|
is-glob: "npm:^4.0.3"
|
||||||
|
|
@ -1605,32 +1624,32 @@ __metadata:
|
||||||
ts-api-utils: "npm:^2.1.0"
|
ts-api-utils: "npm:^2.1.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: ">=4.8.4 <6.0.0"
|
typescript: ">=4.8.4 <6.0.0"
|
||||||
checksum: 10c0/cef0827614cf33eab54de2f671c6e6d8cab45286ea4980e8205a7a50504e0c0984f1c12c69c7046ee3aedf29a745f0c823324dcd36c59c81b179517d6de5017f
|
checksum: 10c0/8c2f44a00fe859a6cd4b50157c484c5b6a1c7af5d48e89ae79c5f4924947964962fc8f478ad4c2ade788907fceee9b72d4e376508ea79b51392f91082a37d239
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/utils@npm:8.44.1":
|
"@typescript-eslint/utils@npm:8.45.0":
|
||||||
version: 8.44.1
|
version: 8.45.0
|
||||||
resolution: "@typescript-eslint/utils@npm:8.44.1"
|
resolution: "@typescript-eslint/utils@npm:8.45.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@eslint-community/eslint-utils": "npm:^4.7.0"
|
"@eslint-community/eslint-utils": "npm:^4.7.0"
|
||||||
"@typescript-eslint/scope-manager": "npm:8.44.1"
|
"@typescript-eslint/scope-manager": "npm:8.45.0"
|
||||||
"@typescript-eslint/types": "npm:8.44.1"
|
"@typescript-eslint/types": "npm:8.45.0"
|
||||||
"@typescript-eslint/typescript-estree": "npm:8.44.1"
|
"@typescript-eslint/typescript-estree": "npm:8.45.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
typescript: ">=4.8.4 <6.0.0"
|
typescript: ">=4.8.4 <6.0.0"
|
||||||
checksum: 10c0/5f855c8a18c3112160c04d1d7bad5abee5e4712574d2f75b8a898f4e132e6e0dee3112f98010a1def47bbf0ac2fb05b6e81d343e577d144769a8d685b42b0809
|
checksum: 10c0/b3c83a23813b15e20e303d7153789508c01e06dec355b1a80547c59aa36998d498102f45fcd13f111031fac57270608abb04d20560248d4448fd00b1cf4dc4ab
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys@npm:8.44.1":
|
"@typescript-eslint/visitor-keys@npm:8.45.0":
|
||||||
version: 8.44.1
|
version: 8.45.0
|
||||||
resolution: "@typescript-eslint/visitor-keys@npm:8.44.1"
|
resolution: "@typescript-eslint/visitor-keys@npm:8.45.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types": "npm:8.44.1"
|
"@typescript-eslint/types": "npm:8.45.0"
|
||||||
eslint-visitor-keys: "npm:^4.2.1"
|
eslint-visitor-keys: "npm:^4.2.1"
|
||||||
checksum: 10c0/b2b06c9c45b1c27d9fc05805a5d6bac3cf8f17d2ccaa59bd40718e911df474b47b85dbab3494522917d9ba469338246f226b5332c3be2da52636f8a3b842fbf7
|
checksum: 10c0/119adcf50c902dad7f7757bcdd88fad0a23a171d309d9b7cefe78af12e451cf84c04ae611f4c31f7e23f16c2b47665ad92e6e5648fc77d542ef306f465bf1f29
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -1679,19 +1698,19 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@vitejs/plugin-react@npm:^5.0.3":
|
"@vitejs/plugin-react@npm:^5.0.4":
|
||||||
version: 5.0.3
|
version: 5.0.4
|
||||||
resolution: "@vitejs/plugin-react@npm:5.0.3"
|
resolution: "@vitejs/plugin-react@npm:5.0.4"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core": "npm:^7.28.4"
|
"@babel/core": "npm:^7.28.4"
|
||||||
"@babel/plugin-transform-react-jsx-self": "npm:^7.27.1"
|
"@babel/plugin-transform-react-jsx-self": "npm:^7.27.1"
|
||||||
"@babel/plugin-transform-react-jsx-source": "npm:^7.27.1"
|
"@babel/plugin-transform-react-jsx-source": "npm:^7.27.1"
|
||||||
"@rolldown/pluginutils": "npm:1.0.0-beta.35"
|
"@rolldown/pluginutils": "npm:1.0.0-beta.38"
|
||||||
"@types/babel__core": "npm:^7.20.5"
|
"@types/babel__core": "npm:^7.20.5"
|
||||||
react-refresh: "npm:^0.17.0"
|
react-refresh: "npm:^0.17.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
|
vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
|
||||||
checksum: 10c0/3fc071455630a0584c170c544d20fc3edaccfb60a1e03ea14ca76f049f2657eb645aba9c216db016b8d70e4f894285a78fcd92ef63a2fcfa7864da378ac52761
|
checksum: 10c0/bb9360a4b4c0abf064d22211756b999faf23889ac150de490590ca7bd029b0ef7f4cd8ba3a32b86682a62d46fb7bebd75b3fa9835c57c78123f4a646de2e0136
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -2452,15 +2471,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"color-convert@npm:^1.9.3":
|
|
||||||
version: 1.9.3
|
|
||||||
resolution: "color-convert@npm:1.9.3"
|
|
||||||
dependencies:
|
|
||||||
color-name: "npm:1.1.3"
|
|
||||||
checksum: 10c0/5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"color-convert@npm:^2.0.1":
|
"color-convert@npm:^2.0.1":
|
||||||
version: 2.0.1
|
version: 2.0.1
|
||||||
resolution: "color-convert@npm:2.0.1"
|
resolution: "color-convert@npm:2.0.1"
|
||||||
|
|
@ -2470,47 +2480,45 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"color-name@npm:1.1.3":
|
"color-convert@npm:^3.0.1":
|
||||||
version: 1.1.3
|
version: 3.1.2
|
||||||
resolution: "color-name@npm:1.1.3"
|
resolution: "color-convert@npm:3.1.2"
|
||||||
checksum: 10c0/566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6
|
dependencies:
|
||||||
|
color-name: "npm:^2.0.0"
|
||||||
|
checksum: 10c0/5b83147015024931a06b57b197d09fc1f67f2efc93dfea5f042aba4788a95b13aebe511b0a929e0e837e442fd91a60c27de8e6761ff30e1a1e2fb634cca8a976
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"color-name@npm:^1.0.0, color-name@npm:~1.1.4":
|
"color-name@npm:^2.0.0":
|
||||||
|
version: 2.0.2
|
||||||
|
resolution: "color-name@npm:2.0.2"
|
||||||
|
checksum: 10c0/40372a581fdeca099b824b6a14dac095387ae83457ed0fafe6f37053515c1094365f0d26b5f29df941be748051b490a0aa3f2ea0c29126a90ab2add482942701
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"color-name@npm:~1.1.4":
|
||||||
version: 1.1.4
|
version: 1.1.4
|
||||||
resolution: "color-name@npm:1.1.4"
|
resolution: "color-name@npm:1.1.4"
|
||||||
checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95
|
checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"color-string@npm:^1.6.0":
|
"color-string@npm:^2.0.0":
|
||||||
version: 1.9.1
|
version: 2.1.2
|
||||||
resolution: "color-string@npm:1.9.1"
|
resolution: "color-string@npm:2.1.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
color-name: "npm:^1.0.0"
|
color-name: "npm:^2.0.0"
|
||||||
simple-swizzle: "npm:^0.2.2"
|
checksum: 10c0/d1d3e8123b2a6a6715e539b347ce000925305946092d566697bb872b1b8951a8699a842b4e5e6324733bef7e4cd3517c50aeecf2a6aae12efc7ca5697ac95178
|
||||||
checksum: 10c0/b0bfd74c03b1f837f543898b512f5ea353f71630ccdd0d66f83028d1f0924a7d4272deb278b9aef376cacf1289b522ac3fb175e99895283645a2dc3a33af2404
|
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"color@npm:^3.1.3":
|
"color@npm:^5.0.2":
|
||||||
version: 3.2.1
|
version: 5.0.2
|
||||||
resolution: "color@npm:3.2.1"
|
resolution: "color@npm:5.0.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
color-convert: "npm:^1.9.3"
|
color-convert: "npm:^3.0.1"
|
||||||
color-string: "npm:^1.6.0"
|
color-string: "npm:^2.0.0"
|
||||||
checksum: 10c0/39345d55825884c32a88b95127d417a2c24681d8b57069413596d9fcbb721459ef9d9ec24ce3e65527b5373ce171b73e38dbcd9c830a52a6487e7f37bf00e83c
|
checksum: 10c0/a5eeee197651a5fe84ab578a8477827e2c2e56b82832aae2b6c60469240be3bc1f03f99686223b1c4e48107c9e20b980475524faab7e6bab1cb9104313910f0e
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"colorspace@npm:1.1.x":
|
|
||||||
version: 1.1.4
|
|
||||||
resolution: "colorspace@npm:1.1.4"
|
|
||||||
dependencies:
|
|
||||||
color: "npm:^3.1.3"
|
|
||||||
text-hex: "npm:1.0.x"
|
|
||||||
checksum: 10c0/af5f91ff7f8e146b96e439ac20ed79b197210193bde721b47380a75b21751d90fa56390c773bb67c0aedd34ff85091883a437ab56861c779bd507d639ba7e123
|
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -2574,16 +2582,16 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"cross-env@npm:^10.0.0":
|
"cross-env@npm:^10.1.0":
|
||||||
version: 10.0.0
|
version: 10.1.0
|
||||||
resolution: "cross-env@npm:10.0.0"
|
resolution: "cross-env@npm:10.1.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@epic-web/invariant": "npm:^1.0.0"
|
"@epic-web/invariant": "npm:^1.0.0"
|
||||||
cross-spawn: "npm:^7.0.6"
|
cross-spawn: "npm:^7.0.6"
|
||||||
bin:
|
bin:
|
||||||
cross-env: dist/bin/cross-env.js
|
cross-env: dist/bin/cross-env.js
|
||||||
cross-env-shell: dist/bin/cross-env-shell.js
|
cross-env-shell: dist/bin/cross-env-shell.js
|
||||||
checksum: 10c0/d16ffc3734106577d57b6253d81ab50294623bd59f96e161033eaf99c1c308ffbaba8463c23a6c0f72e841eff467cb7007a0a551f27554fcf2bbf6598cd828f9
|
checksum: 10c0/834a862db456ba1fedf6c6da43436b123ae38f514fa286d6f0937c14fa83f13469f77f70f2812db041ae2d84f82bac627040b8686030aca27fbdf113dfa38b63
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -2929,16 +2937,16 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"electron@npm:^38.1.2":
|
"electron@npm:^38.2.0":
|
||||||
version: 38.1.2
|
version: 38.2.0
|
||||||
resolution: "electron@npm:38.1.2"
|
resolution: "electron@npm:38.2.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@electron/get": "npm:^2.0.0"
|
"@electron/get": "npm:^2.0.0"
|
||||||
"@types/node": "npm:^22.7.7"
|
"@types/node": "npm:^22.7.7"
|
||||||
extract-zip: "npm:^2.0.1"
|
extract-zip: "npm:^2.0.1"
|
||||||
bin:
|
bin:
|
||||||
electron: cli.js
|
electron: cli.js
|
||||||
checksum: 10c0/63f768e8ac396221db17c280e483ac838067e881ee61eb78c5c8f587017e51c587cc1eb687f29672b5e63c0af8a5d818d721d49aef20bac082544a8cf2d323ea
|
checksum: 10c0/86c1a429b11d273c606d6827bdd114e6b0d57c8d12867e27c3f8542f1f5d85bda8da4330d17ad1556007860e4b2ac6aa71699a0648c9021bfdd83e4224e01c20
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -3860,21 +3868,21 @@ __metadata:
|
||||||
dependencies:
|
dependencies:
|
||||||
"@codemirror/search": "npm:^6.5.11"
|
"@codemirror/search": "npm:^6.5.11"
|
||||||
"@codemirror/theme-one-dark": "npm:^6.1.3"
|
"@codemirror/theme-one-dark": "npm:^6.1.3"
|
||||||
"@codemirror/view": "npm:^6.38.3"
|
"@codemirror/view": "npm:^6.38.4"
|
||||||
"@eslint/js": "npm:^9.36.0"
|
"@eslint/js": "npm:^9.36.0"
|
||||||
"@fontsource/inter": "npm:^5.2.8"
|
"@fontsource/inter": "npm:^5.2.8"
|
||||||
"@mantine/core": "npm:8.3.1"
|
"@mantine/core": "npm:8.3.1"
|
||||||
"@mantine/hooks": "npm:8.3.1"
|
"@mantine/hooks": "npm:8.3.1"
|
||||||
"@types/node": "npm:^24.5.2"
|
"@types/node": "npm:^24.6.1"
|
||||||
"@types/react": "npm:^19.1.14"
|
"@types/react": "npm:^19.1.16"
|
||||||
"@types/react-dom": "npm:^19.1.9"
|
"@types/react-dom": "npm:^19.1.9"
|
||||||
"@types/yauzl": "npm:^2.10.3"
|
"@types/yauzl": "npm:^2.10.3"
|
||||||
"@typescript-eslint/eslint-plugin": "npm:^8.44.1"
|
"@typescript-eslint/eslint-plugin": "npm:^8.45.0"
|
||||||
"@typescript-eslint/parser": "npm:^8.44.1"
|
"@typescript-eslint/parser": "npm:^8.45.0"
|
||||||
"@uiw/react-codemirror": "npm:^4.25.2"
|
"@uiw/react-codemirror": "npm:^4.25.2"
|
||||||
"@vitejs/plugin-react": "npm:^5.0.3"
|
"@vitejs/plugin-react": "npm:^5.0.4"
|
||||||
cross-env: "npm:^10.0.0"
|
cross-env: "npm:^10.1.0"
|
||||||
electron: "npm:^38.1.2"
|
electron: "npm:^38.2.0"
|
||||||
electron-builder: "npm:^26.0.12"
|
electron-builder: "npm:^26.0.12"
|
||||||
electron-updater: "npm:6.6.2"
|
electron-updater: "npm:6.6.2"
|
||||||
electron-vite: "npm:^4.0.1"
|
electron-vite: "npm:^4.0.1"
|
||||||
|
|
@ -3895,9 +3903,9 @@ __metadata:
|
||||||
react-error-boundary: "npm:^6.0.0"
|
react-error-boundary: "npm:^6.0.0"
|
||||||
rollup-plugin-visualizer: "npm:^6.0.3"
|
rollup-plugin-visualizer: "npm:^6.0.3"
|
||||||
systeminformation: "npm:^5.27.10"
|
systeminformation: "npm:^5.27.10"
|
||||||
typescript: "npm:^5.9.2"
|
typescript: "npm:^5.9.3"
|
||||||
vite: "npm:^7.1.7"
|
vite: "npm:^7.1.7"
|
||||||
winston: "npm:^3.17.0"
|
winston: "npm:^3.18.3"
|
||||||
winston-daily-rotate-file: "npm:^5.0.0"
|
winston-daily-rotate-file: "npm:^5.0.0"
|
||||||
yauzl: "npm:^3.2.0"
|
yauzl: "npm:^3.2.0"
|
||||||
zustand: "npm:^5.0.8"
|
zustand: "npm:^5.0.8"
|
||||||
|
|
@ -4372,13 +4380,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"is-arrayish@npm:^0.3.1":
|
|
||||||
version: 0.3.4
|
|
||||||
resolution: "is-arrayish@npm:0.3.4"
|
|
||||||
checksum: 10c0/1fa672a2f0bedb74154440310f616c0b6e53a95cf0625522ae050f06626d1cabd1a3d8085c882dc45c61ad0e7df2529aff122810b3b4a552880bf170d6df94e0
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"is-async-function@npm:^2.0.0":
|
"is-async-function@npm:^2.0.0":
|
||||||
version: 2.1.1
|
version: 2.1.1
|
||||||
resolution: "is-async-function@npm:2.1.1"
|
resolution: "is-async-function@npm:2.1.1"
|
||||||
|
|
@ -6601,15 +6602,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"simple-swizzle@npm:^0.2.2":
|
|
||||||
version: 0.2.4
|
|
||||||
resolution: "simple-swizzle@npm:0.2.4"
|
|
||||||
dependencies:
|
|
||||||
is-arrayish: "npm:^0.3.1"
|
|
||||||
checksum: 10c0/846c3fdd1325318d5c71295cfbb99bfc9edc4c8dffdda5e6e9efe30482bbcd32cf360fc2806f46ac43ff7d09bcfaff20337bb79f826f0e6a8e366efd3cdd7868
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"simple-update-notifier@npm:2.0.0":
|
"simple-update-notifier@npm:2.0.0":
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
resolution: "simple-update-notifier@npm:2.0.0"
|
resolution: "simple-update-notifier@npm:2.0.0"
|
||||||
|
|
@ -7152,23 +7144,23 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"typescript@npm:>=5, typescript@npm:^5.9.2":
|
"typescript@npm:>=5, typescript@npm:^5.9.3":
|
||||||
version: 5.9.2
|
version: 5.9.3
|
||||||
resolution: "typescript@npm:5.9.2"
|
resolution: "typescript@npm:5.9.3"
|
||||||
bin:
|
bin:
|
||||||
tsc: bin/tsc
|
tsc: bin/tsc
|
||||||
tsserver: bin/tsserver
|
tsserver: bin/tsserver
|
||||||
checksum: 10c0/cd635d50f02d6cf98ed42de2f76289701c1ec587a363369255f01ed15aaf22be0813226bff3c53e99d971f9b540e0b3cc7583dbe05faded49b1b0bed2f638a18
|
checksum: 10c0/6bd7552ce39f97e711db5aa048f6f9995b53f1c52f7d8667c1abdc1700c68a76a308f579cd309ce6b53646deb4e9a1be7c813a93baaf0a28ccd536a30270e1c5
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"typescript@patch:typescript@npm%3A>=5#optional!builtin<compat/typescript>, typescript@patch:typescript@npm%3A^5.9.2#optional!builtin<compat/typescript>":
|
"typescript@patch:typescript@npm%3A>=5#optional!builtin<compat/typescript>, typescript@patch:typescript@npm%3A^5.9.3#optional!builtin<compat/typescript>":
|
||||||
version: 5.9.2
|
version: 5.9.3
|
||||||
resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin<compat/typescript>::version=5.9.2&hash=5786d5"
|
resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin<compat/typescript>::version=5.9.3&hash=5786d5"
|
||||||
bin:
|
bin:
|
||||||
tsc: bin/tsc
|
tsc: bin/tsc
|
||||||
tsserver: bin/tsserver
|
tsserver: bin/tsserver
|
||||||
checksum: 10c0/34d2a8e23eb8e0d1875072064d5e1d9c102e0bdce56a10a25c0b917b8aa9001a9cf5c225df12497e99da107dc379360bc138163c66b55b95f5b105b50578067e
|
checksum: 10c0/ad09fdf7a756814dce65bc60c1657b40d44451346858eea230e10f2e95a289d9183b6e32e5c11e95acc0ccc214b4f36289dcad4bf1886b0adb84d711d336a430
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -7191,10 +7183,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"undici-types@npm:~7.12.0":
|
"undici-types@npm:~7.13.0":
|
||||||
version: 7.12.0
|
version: 7.13.0
|
||||||
resolution: "undici-types@npm:7.12.0"
|
resolution: "undici-types@npm:7.13.0"
|
||||||
checksum: 10c0/326e455bbc0026db1d6b81c76a1cf10c63f7e2f9821db2e24fdc258f482814e5bfa8481f8910d07c68e305937c5c049610fdc441c5e8b7bb0daca7154fb8a306
|
checksum: 10c0/44bbb0935425291351bfd8039571f017295b5d6dc5727045d0a4fea8c6ffe73a6703b48ce010f9cb539b9041a75b463f8cfe1e7309cab7486452505fb0d66151
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -7551,12 +7543,12 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"winston@npm:^3.17.0":
|
"winston@npm:^3.18.3":
|
||||||
version: 3.17.0
|
version: 3.18.3
|
||||||
resolution: "winston@npm:3.17.0"
|
resolution: "winston@npm:3.18.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@colors/colors": "npm:^1.6.0"
|
"@colors/colors": "npm:^1.6.0"
|
||||||
"@dabh/diagnostics": "npm:^2.0.2"
|
"@dabh/diagnostics": "npm:^2.0.8"
|
||||||
async: "npm:^3.2.3"
|
async: "npm:^3.2.3"
|
||||||
is-stream: "npm:^2.0.0"
|
is-stream: "npm:^2.0.0"
|
||||||
logform: "npm:^2.7.0"
|
logform: "npm:^2.7.0"
|
||||||
|
|
@ -7566,7 +7558,7 @@ __metadata:
|
||||||
stack-trace: "npm:0.0.x"
|
stack-trace: "npm:0.0.x"
|
||||||
triple-beam: "npm:^1.3.0"
|
triple-beam: "npm:^1.3.0"
|
||||||
winston-transport: "npm:^4.9.0"
|
winston-transport: "npm:^4.9.0"
|
||||||
checksum: 10c0/ec8eaeac9a72b2598aedbff50b7dac82ce374a400ed92e7e705d7274426b48edcb25507d78cff318187c4fb27d642a0e2a39c57b6badc9af8e09d4a40636a5f7
|
checksum: 10c0/0bd666590d7f1f2e1fa1273b699463e14b2fcf2bab503e16bc62f275c4b52f14c3dda7bb255d5cc4cef046dd3e112c45518ec8f3c3536ab666421b7265d8c45b
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue