diff --git a/client/web/plugins/com.msgbyte.env.electron/manifest.json b/client/web/plugins/com.msgbyte.env.electron/manifest.json
new file mode 100644
index 00000000..82427818
--- /dev/null
+++ b/client/web/plugins/com.msgbyte.env.electron/manifest.json
@@ -0,0 +1,11 @@
+{
+ "label": "Electron Support",
+ "label.zh-CN": "Electron 支持",
+ "name": "com.msgbyte.env.electron",
+ "url": "/plugins/com.msgbyte.env.electron/index.js",
+ "version": "0.0.0",
+ "author": "moonrailgun",
+ "description": "Add support for Electron environment in Tailchat",
+ "description.zh-CN": "在 Tailchat 添加对 Electron 环境的支持",
+ "requireRestart": true
+}
diff --git a/client/web/plugins/com.msgbyte.env.electron/package.json b/client/web/plugins/com.msgbyte.env.electron/package.json
new file mode 100644
index 00000000..7a3f6171
--- /dev/null
+++ b/client/web/plugins/com.msgbyte.env.electron/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "@plugins/com.msgbyte.env.electron",
+ "main": "src/index.tsx",
+ "version": "0.0.0",
+ "description": "Add support for Electron environment in Tailchat",
+ "private": true,
+ "scripts": {
+ "sync:declaration": "tailchat declaration github"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "@types/styled-components": "^5.1.26",
+ "react": "18.2.0",
+ "styled-components": "^5.3.6"
+ }
+}
diff --git a/client/web/plugins/com.msgbyte.env.electron/src/DeviceInfoPanel.tsx b/client/web/plugins/com.msgbyte.env.electron/src/DeviceInfoPanel.tsx
new file mode 100644
index 00000000..682ece08
--- /dev/null
+++ b/client/web/plugins/com.msgbyte.env.electron/src/DeviceInfoPanel.tsx
@@ -0,0 +1,19 @@
+import React from 'react';
+import { Translate } from './translate';
+
+interface WindowElectronDeviceInfo {
+ version: string;
+}
+
+export const DeviceInfoPanel: React.FC = React.memo(() => {
+ const deviceInfo: WindowElectronDeviceInfo =
+ (window as any).__electronDeviceInfo ?? {};
+ return (
+
+
+ {Translate.clientVersion}: {deviceInfo.version}
+
+
+ );
+});
+DeviceInfoPanel.displayName = 'DeviceInfoPanel';
diff --git a/client/web/plugins/com.msgbyte.env.electron/src/index.tsx b/client/web/plugins/com.msgbyte.env.electron/src/index.tsx
new file mode 100644
index 00000000..adde2286
--- /dev/null
+++ b/client/web/plugins/com.msgbyte.env.electron/src/index.tsx
@@ -0,0 +1,15 @@
+import { regCustomPanel } from '@capital/common';
+import { DeviceInfoPanel } from './DeviceInfoPanel';
+import { Translate } from './translate';
+
+const PLUGIN_NAME = 'Electron Support';
+
+console.log(`Plugin ${PLUGIN_NAME} is loaded`);
+
+regCustomPanel({
+ position: 'setting',
+ icon: '',
+ name: 'com.msgbyte.env.electron/deviceInfoPanel',
+ label: Translate.deviceInfo,
+ render: DeviceInfoPanel,
+});
diff --git a/client/web/plugins/com.msgbyte.env.electron/src/translate.ts b/client/web/plugins/com.msgbyte.env.electron/src/translate.ts
new file mode 100644
index 00000000..99434f68
--- /dev/null
+++ b/client/web/plugins/com.msgbyte.env.electron/src/translate.ts
@@ -0,0 +1,12 @@
+import { localTrans } from '@capital/common';
+
+export const Translate = {
+ deviceInfo: localTrans({
+ 'zh-CN': '设备信息',
+ 'en-US': 'Device Info',
+ }),
+ clientVersion: localTrans({
+ 'zh-CN': '客户端版本号',
+ 'en-US': 'Client Version',
+ }),
+};
diff --git a/client/web/plugins/com.msgbyte.env.electron/tsconfig.json b/client/web/plugins/com.msgbyte.env.electron/tsconfig.json
new file mode 100644
index 00000000..d9b47ed0
--- /dev/null
+++ b/client/web/plugins/com.msgbyte.env.electron/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "compilerOptions": {
+ "esModuleInterop": true,
+ "jsx": "react",
+ "importsNotUsedAsValues": "error"
+ }
+}
diff --git a/client/web/plugins/com.msgbyte.env.electron/types/tailchat.d.ts b/client/web/plugins/com.msgbyte.env.electron/types/tailchat.d.ts
new file mode 100644
index 00000000..49f524ae
--- /dev/null
+++ b/client/web/plugins/com.msgbyte.env.electron/types/tailchat.d.ts
@@ -0,0 +1,2 @@
+declare module '@capital/common';
+declare module '@capital/component';
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index bda2cbb1..b759de7b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1049,6 +1049,18 @@ importers:
specifier: 18.2.0
version: 18.2.0
+ client/web/plugins/com.msgbyte.env.electron:
+ devDependencies:
+ '@types/styled-components':
+ specifier: ^5.1.26
+ version: 5.1.26
+ react:
+ specifier: 18.2.0
+ version: 18.2.0
+ styled-components:
+ specifier: ^5.3.6
+ version: 5.3.6(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0)
+
client/web/plugins/com.msgbyte.env.rn:
devDependencies:
'@types/styled-components':