diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 35efece..f5e159a 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -9,10 +9,10 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: setup node
-        uses: actions/setup-node@v2
+        uses: actions/setup-node@v4
         with:
           node-version: 18
 
diff --git a/.gitignore b/.gitignore
index 0dc9ec5..a3d980a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,15 @@
-node_modules/
+.yarn/*
+!.yarn/patches
+!.yarn/plugins
+!.yarn/releases
+!.yarn/sdks
+!.yarn/versions
+
 package-lock.json
-dist/
-out/
+yarn.lock
+node_modules
+dist
+out
+
 .idea/
 .DS_Store
diff --git a/.yarnrc.yml b/.yarnrc.yml
new file mode 100644
index 0000000..3186f3f
--- /dev/null
+++ b/.yarnrc.yml
@@ -0,0 +1 @@
+nodeLinker: node-modules
diff --git a/README.md b/README.md
index 333f2a6..ca1690e 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
 # LLOneBot
 
-LiteLoaderQQNT插件,使你的NTQQ支持OneBot11协议进行QQ机器人开发
+LiteLoaderQQNT 插件,实现 OneBot 11 协议,用以 QQ 机器人开发
 
 > [!CAUTION]\
-> **请不要在 QQ 官方群聊和任何影响力较大的简中互联网平台(包括但不限于:B站,微博,知乎,抖音等)发布和讨论*任何*与本插件存在相关性的信息**
+> **请不要在 QQ 官方群聊和任何影响力较大的简中互联网平台(包括但不限于: B站,微博,知乎,抖音等)发布和讨论*任何*与本插件存在相关性的信息**
 
 TG群:<https://t.me/+nLZEnpne-pQ1OWFl>
 
@@ -13,13 +13,13 @@ TG群:<https://t.me/+nLZEnpne-pQ1OWFl>
 
 ## 设置界面
 
-<img src="./doc/image/setting.png" width="500px" alt="图片名称"/>
+<img src="./doc/image/setting.png" width="400px" alt="设置界面"/>
 
 ## HTTP 调用示例
 
-![](doc/image/example.jpg)
+<img src="./doc/image/example.jpg" width="500px" alt="HTTP调用示例"/>
 
-## 支持的 api 和功能详情
+## 支持的 API
 
 见 <https://llonebot.github.io/zh-CN/develop/api>
 
@@ -35,13 +35,8 @@ TG群:<https://t.me/+nLZEnpne-pQ1OWFl>
 - [x] 群禁言事件上报
 - [x] 优化加群成功事件上报
 - [x] 清理缓存api
-- [ ] 无头模式
 - [ ] 框架对接文档
 
-## onebot11文档
-
-<https://11.onebot.dev/>
-
 ## Stargazers over time
 
 [![Stargazers over time](https://starchart.cc/LLOneBot/LLOneBot.svg?variant=adaptive)](https://starchart.cc/LLOneBot/LLOneBot)
diff --git a/electron.vite.config.ts b/electron.vite.config.ts
index a469511..1259f35 100644
--- a/electron.vite.config.ts
+++ b/electron.vite.config.ts
@@ -1,6 +1,6 @@
 import cp from 'vite-plugin-cp'
-import './scripts/gen-version'
 import path from 'node:path'
+import './scripts/gen-manifest'
 
 const external = [
   'silk-wasm',
@@ -32,6 +32,7 @@ let config = {
         external,
         input: 'src/main/main.ts',
       },
+      minify: true,
     },
     resolve: {
       alias: {
@@ -44,8 +45,8 @@ let config = {
         targets: [
           ...external.map(genCpModule),
           { src: './manifest.json', dest: 'dist' },
-          { src: './icon.jpg', dest: 'dist' },
-          { src: './src/ntqqapi/native/crychic/crychic-win32-x64.node', dest: 'dist/main/' },
+          { src: './icon.webp', dest: 'dist' },
+          // { src: './src/ntqqapi/native/crychic/crychic-win32-x64.node', dest: 'dist/main/' },
           // { src: './src/ntqqapi/native/moehook/MoeHoo-win32-x64.node', dest: 'dist/main/' },
           // { src: './src/ntqqapi/native/moehook/MoeHoo-linux-x64.node', dest: 'dist/main/' },
         ],
diff --git a/icon.jpg b/icon.jpg
deleted file mode 100644
index 67ca0da..0000000
Binary files a/icon.jpg and /dev/null differ
diff --git a/icon.webp b/icon.webp
new file mode 100644
index 0000000..5f07709
Binary files /dev/null and b/icon.webp differ
diff --git a/manifest.json b/manifest.json
index dbd0073..f6e8266 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,11 +1,11 @@
 {
   "manifest_version": 4,
   "type": "extension",
-  "name": "LLOneBot v3.27.4",
+  "name": "LLOneBot",
   "slug": "LLOneBot",
-  "description": "使你的NTQQ支持OneBot11协议进行QQ机器人开发",
+  "description": "实现 OneBot 11 协议,帮助进行 QQ 机器人开发",
   "version": "3.27.4",
-  "icon": "./icon.jpg",
+  "icon": "./icon.webp",
   "authors": [
     {
       "name": "linyuchen",
diff --git a/package.json b/package.json
index 25882bf..d4f13ae 100644
--- a/package.json
+++ b/package.json
@@ -31,16 +31,11 @@
     "@types/fluent-ffmpeg": "^2.1.24",
     "@types/node": "^20.11.24",
     "@types/ws": "^8.5.12",
-    "@typescript-eslint/eslint-plugin": "^6.4.0",
     "electron": "^29.0.1",
-    "electron-vite": "^2.0.0",
-    "eslint": "^8.0.1",
-    "eslint-plugin-import": "^2.25.2",
-    "eslint-plugin-n": "^15.0.0 || ^16.0.0",
-    "eslint-plugin-promise": "^6.0.0",
-    "ts-node": "^10.9.2",
-    "typescript": "*",
-    "vite": "^5.1.4",
+    "electron-vite": "^2.3.0",
+    "typescript": "^5.5.4",
+    "vite": "^5.3.5",
     "vite-plugin-cp": "^4.0.8"
-  }
+  },
+  "packageManager": "yarn@4.4.0"
 }
diff --git a/scripts/gen-manifest.ts b/scripts/gen-manifest.ts
new file mode 100644
index 0000000..a4b41a6
--- /dev/null
+++ b/scripts/gen-manifest.ts
@@ -0,0 +1,38 @@
+import { version } from '../src/version'
+import { writeFileSync } from 'node:fs'
+
+const manifest = {
+  manifest_version: 4,
+  type: 'extension',
+  name: 'LLOneBot',
+  slug: 'LLOneBot',
+  description: '实现 OneBot 11 协议,用以 QQ 机器人开发',
+  version,
+  icon: './icon.webp',
+  authors: [
+    {
+      name: 'linyuchen',
+      link: 'https://github.com/linyuchen'
+    }
+  ],
+  repository: {
+    repo: 'linyuchen/LiteLoaderQQNT-OneBotApi',
+    branch: 'main',
+    release: {
+      tag: 'latest',
+      name: 'LLOneBot.zip'
+    }
+  },
+  platform: [
+    'win32',
+    'linux',
+    'darwin'
+  ],
+  injects: {
+    renderer: './renderer/index.js',
+    main: './main/main.cjs',
+    preload: './preload/preload.cjs'
+  }
+}
+
+writeFileSync('manifest.json', JSON.stringify(manifest, null, 2))
\ No newline at end of file
diff --git a/scripts/gen-version.ts b/scripts/gen-version.ts
deleted file mode 100644
index b702dee..0000000
--- a/scripts/gen-version.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import fs from 'fs'
-import path from 'path'
-import { version } from '../src/version'
-
-const manifestPath = path.join(__dirname, '../manifest.json')
-
-function readManifest(): any {
-  if (fs.existsSync(manifestPath)) {
-    return JSON.parse(fs.readFileSync(manifestPath, 'utf-8'))
-  }
-}
-
-function writeManifest(manifest: any) {
-  fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2))
-}
-
-const manifest = readManifest()
-if (version !== manifest.version) {
-  manifest.version = version
-  manifest.name = `LLOneBot v${version}`
-  writeManifest(manifest)
-}
diff --git a/src/common/config.ts b/src/common/config.ts
index 3d039a7..d9a1eea 100644
--- a/src/common/config.ts
+++ b/src/common/config.ts
@@ -53,7 +53,6 @@ export class ConfigUtil {
       reportSelfMessage: false,
       autoDeleteFile: false,
       autoDeleteFileSecond: 60,
-      enablePoke: false,
       musicSignUrl: '',
     }
 
diff --git a/src/common/types.ts b/src/common/types.ts
index 80f15e0..b4d722d 100644
--- a/src/common/types.ts
+++ b/src/common/types.ts
@@ -28,7 +28,6 @@ export interface Config {
   autoDeleteFile?: boolean
   autoDeleteFileSecond?: number
   ffmpeg?: string // ffmpeg路径
-  enablePoke?: boolean
   musicSignUrl?: string
   ignoreBeforeLoginMsg?: boolean
 }
diff --git a/src/common/utils/file.ts b/src/common/utils/file.ts
index c400e80..2b2aafa 100644
--- a/src/common/utils/file.ts
+++ b/src/common/utils/file.ts
@@ -1,11 +1,9 @@
-import fs from 'fs'
-import fsPromise from 'fs/promises'
-import util from 'util'
+import fs from 'node:fs'
+import fsPromise from 'node:fs/promises'
 import path from 'node:path'
 import { log, TEMP_DIR } from './index'
 import { dbUtil } from '../db'
 import * as fileType from 'file-type'
-import { net } from 'electron'
 import { randomUUID, createHash } from 'node:crypto'
 
 export function isGIF(path: string) {
@@ -36,7 +34,6 @@ export function checkFileReceived(path: string, timeout: number = 3000): Promise
 }
 
 export async function file2base64(path: string) {
-  const readFile = util.promisify(fs.readFile)
   let result = {
     err: '',
     data: '',
@@ -52,7 +49,7 @@ export async function file2base64(path: string) {
       result.err = e.toString()
       return result
     }
-    const data = await readFile(path)
+    const data = await fsPromise.readFile(path)
     // 转换为Base64编码
     result.data = data.toString('base64')
   } catch (err) {
@@ -90,7 +87,6 @@ export interface HttpDownloadOptions {
   headers?: Record<string, string> | string
 }
 export async function httpDownload(options: string | HttpDownloadOptions): Promise<Buffer> {
-  let chunks: Buffer[] = []
   let url: string
   let headers: Record<string, string> = {
     'User-Agent':
@@ -108,12 +104,10 @@ export async function httpDownload(options: string | HttpDownloadOptions): Promi
       }
     }
   }
-  const fetchRes = await net.fetch(url, { headers })
+  const fetchRes = await fetch(url, { headers })
   if (!fetchRes.ok) throw new Error(`下载文件失败: ${fetchRes.statusText}`)
 
-  const blob = await fetchRes.blob()
-  let buffer = await blob.arrayBuffer()
-  return Buffer.from(buffer)
+  return Buffer.from(await fetchRes.arrayBuffer())
 }
 
 type Uri2LocalRes = {
@@ -152,7 +146,7 @@ export async function uri2local(uri: string, fileName: string = null): Promise<U
     let base64Data = uri.split('base64://')[1]
     try {
       const buffer = Buffer.from(base64Data, 'base64')
-      fs.writeFileSync(filePath, buffer)
+      await fsPromise.writeFile(filePath, buffer)
     } catch (e: any) {
       res.errMsg = `base64文件下载失败,` + e.toString()
       return res
@@ -178,7 +172,7 @@ export async function uri2local(uri: string, fileName: string = null): Promise<U
       fileName = fileName.replace(/[/\\:*?"<>|]/g, '_')
       res.fileName = fileName
       filePath = path.join(TEMP_DIR, randomUUID() + fileName)
-      fs.writeFileSync(filePath, buffer)
+      await fsPromise.writeFile(filePath, buffer)
     } catch (e: any) {
       res.errMsg = `${url}下载失败,` + e.toString()
       return res
@@ -217,7 +211,7 @@ export async function uri2local(uri: string, fileName: string = null): Promise<U
       let ext: string = (await fileType.fileTypeFromFile(filePath)).ext
       if (ext) {
         log('获取文件类型', ext, filePath)
-        fs.renameSync(filePath, filePath + `.${ext}`)
+        await fsPromise.rename(filePath, filePath + `.${ext}`)
         filePath += `.${ext}`
         res.fileName += `.${ext}`
         res.ext = ext
diff --git a/src/global.d.ts b/src/global.d.ts
index 6f1eb56..1baf170 100644
--- a/src/global.d.ts
+++ b/src/global.d.ts
@@ -3,6 +3,6 @@ import { type LLOneBot } from './preload'
 declare global {
   interface Window {
     llonebot: LLOneBot
-    LiteLoader: any
+    LiteLoader: Record<string, any>
   }
 }
diff --git a/src/main/main.ts b/src/main/main.ts
index aadd755..69ac2fe 100644
--- a/src/main/main.ts
+++ b/src/main/main.ts
@@ -48,7 +48,6 @@ import { dbUtil } from '../common/db'
 import { setConfig } from './setConfig'
 import { NTQQUserApi } from '../ntqqapi/api/user'
 import { NTQQGroupApi } from '../ntqqapi/api/group'
-import { crychic } from '../ntqqapi/native/crychic'
 import { OB11FriendPokeEvent, OB11GroupPokeEvent } from '../onebot11/event/notice/OB11PokeEvent'
 import { checkNewVersion, upgradeLLOneBot } from '../common/utils/upgrade'
 import { log } from '../common/utils/log'
@@ -209,26 +208,7 @@ function onLoad() {
   }
 
   async function startReceiveHook() {
-    startHook().then()
-    if (getConfigUtil().getConfig().enablePoke) {
-      if (qqPkgInfo.buildVersion > '23873') {
-        log(`当前版本${qqPkgInfo.buildVersion}不支持发送戳一戳模块`)
-      }
-      else {
-        crychic.loadNode()
-        crychic.registerPokeHandler((id, isGroup) => {
-          log(`收到戳一戳消息了!是否群聊:${isGroup},id:${id}`)
-          let pokeEvent: OB11FriendPokeEvent | OB11GroupPokeEvent
-          if (isGroup) {
-            pokeEvent = new OB11GroupPokeEvent(parseInt(id))
-          }
-          else {
-            pokeEvent = new OB11FriendPokeEvent(parseInt(selfInfo.uin), parseInt(id))
-          }
-          postOb11Event(pokeEvent)
-        })
-      }
-    }
+    startHook()
     registerReceiveHook<{
       msgList: Array<RawMessage>
     }>([ReceiveCmdS.NEW_MSG, ReceiveCmdS.NEW_ACTIVE_MSG], async (payload) => {
diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts
index 2a33c8d..4f88a32 100644
--- a/src/ntqqapi/hook.ts
+++ b/src/ntqqapi/hook.ts
@@ -1,4 +1,4 @@
-import { BrowserWindow } from 'electron'
+import type { BrowserWindow } from 'electron'
 import { NTQQApiClass, NTQQApiMethod } from './ntcall'
 import { NTQQMsgApi, sendMessagePool } from './api/msg'
 import { CategoryFriend, ChatType, Group, GroupMember, GroupMemberRole, RawMessage, User } from './types'
diff --git a/src/onebot11/action/msg/SendMsg.ts b/src/onebot11/action/msg/SendMsg.ts
index 2c92a51..b5eb8b2 100644
--- a/src/onebot11/action/msg/SendMsg.ts
+++ b/src/onebot11/action/msg/SendMsg.ts
@@ -23,7 +23,7 @@ import {
   OB11MessageVideo,
   OB11PostSendMsg,
 } from '../../types'
-import { NTQQMsgApi, Peer } from '../../../ntqqapi/api/msg'
+import { NTQQMsgApi } from '../../../ntqqapi/api/msg'
 import { SendMsgElementConstructor } from '../../../ntqqapi/constructor'
 import BaseAction from '../BaseAction'
 import { ActionName, BaseCheckResult } from '../types'
@@ -37,6 +37,7 @@ import { uri2local } from '../../../common/utils'
 import { crychic } from '../../../ntqqapi/native/crychic'
 import { NTQQGroupApi } from '../../../ntqqapi/api'
 import { CustomMusicSignPostData, IdMusicSignPostData, MusicSign, MusicSignPostData } from '../../../common/utils/sign'
+import { Peer } from '../../../ntqqapi/types/msg'
 
 function checkSendMessage(sendMsgList: OB11MessageData[]) {
   function checkUri(uri: string): boolean {
diff --git a/src/renderer/index.ts b/src/renderer/index.ts
index 8efc0a0..f176c0c 100644
--- a/src/renderer/index.ts
+++ b/src/renderer/index.ts
@@ -4,6 +4,7 @@ import { SettingButton, SettingItem, SettingList, SettingSwitch, SettingSelect }
 // @ts-ignore
 import StyleRaw from './style.css?raw'
 import { iconSvg } from './icon'
+import { version } from '../version'
 
 // 打开设置界面时触发
 
@@ -53,8 +54,8 @@ async function onSettingWindowCreated(view: Element) {
       '<div>',
       `<style>${StyleRaw}</style>`,
       `<setting-section id="llonebot-error">
-            <setting-panel><pre><code></code></pre></setting-panel>
-        </setting-section>`,
+        <setting-panel><pre><code></code></pre></setting-panel>
+      </setting-section>`,
       SettingList([
         SettingItem(
           '<span id="llonebot-update-title">正在检查 LLOneBot 更新</span>',
@@ -186,11 +187,6 @@ async function onSettingWindowCreated(view: Element) {
         SettingItem('', null, SettingButton('保存', 'config-ob11-save', 'primary')),
       ]),
       SettingList([
-        SettingItem(
-          '戳一戳消息, 暂时只支持Windows版的LLOneBot',
-          `重启QQ后生效,如果导致QQ崩溃请勿开启此项, 群戳一戳只能收到群号`,
-          SettingSwitch('enablePoke', config.enablePoke),
-        ),
         SettingItem(
           '使用 Base64 编码获取文件',
           '调用 /get_image、/get_record、/get_file 时,没有 url 时添加 Base64 字段',
@@ -404,7 +400,7 @@ async function onSettingWindowCreated(view: Element) {
     const buttonDom = view.querySelector<HTMLButtonElement>('#llonebot-update-button')!
 
     if (ResultVersion.version === '') {
-      titleDom.innerHTML = '检查更新失败'
+      titleDom.innerHTML = `当前版本为 v${version},检查更新失败`
       buttonDom.innerHTML = '点击重试'
 
       buttonDom.addEventListener('click', async () => {
@@ -414,10 +410,10 @@ async function onSettingWindowCreated(view: Element) {
       return
     }
     if (!ResultVersion.result) {
-      titleDom.innerHTML = '当前已是最新版本 v' + ResultVersion.version
+      titleDom.innerHTML = '当前已是最新版本 v' + version
       buttonDom.innerHTML = '无需更新'
     } else {
-      titleDom.innerHTML = '已检测到最新版本 v' + ResultVersion.version
+      titleDom.innerHTML = `当前版本为 v${version},最新版本为 v${ResultVersion.version}`
       buttonDom.innerHTML = '点击更新'
       buttonDom.dataset.type = 'primary'