diff --git a/.cursor/rules/main.mdc b/.cursor/rules/main.mdc deleted file mode 100644 index 0014815..0000000 --- a/.cursor/rules/main.mdc +++ /dev/null @@ -1,578 +0,0 @@ ---- -description: 使用 WXT、React 和 TypeScript 构建代理管理扩展的指南 -globs: -alwaysApply: false ---- ---- -description: 使用 WXT、React 和 TypeScript 构建代理管理扩展的指南 -globs: "**/*.ts, **/*.tsx, **/*.js, **/*.jsx" ---- - -## 概览 - -](https://wxt.dev/) 是一个为浏览器扩展开发提供现代开发体验的框架。本指南将帮助您使用 WXT、React 和 TypeScript 重构类似 SwitchyOmega 的代理管理扩展。 - -## 项目结构 - -推荐使用以下项目结构: -``` -. -├── .output/ -├── .wxt/ -├── modules/ -├── public/ # 包含要复制到输出文件夹的任何文件,而无需WXT处理 -├── ord/ # 需要重构的旧代码 -├── src/ -│ │ ├── assets/ -│ │ ├── components/ -│ │ ├── composables/ -│ │ ├── entrypoints/ # 包含所有被捆绑到扩展名的入口点 -│ │ ├── hooks/ # 默认自动导入,包含项目用于 React 和 Solid 的钩子的源代码 -│ │ ├── utils/ -├── .env -├── .env.publish -├── app.config.ts -├── package.json -├── tsconfig.json -├── web-ext.config.ts # 配置浏览器启动 -├── wxt.config.ts # WXT项目的主要配置文件 - -``` - - -Different browsers provide different global variables for accessing the extension APIs (chrome provides chrome, firefox provides browser, etc). - -WXT merges these two into a unified API accessed through the browser variable. - -``` -import { browser } from 'wxt/browser'; - -browser.action.onClicked.addListener(() => { -// ... -}); -``` -TIP - -With auto-imports enabled, you don't even need to import this variable from wxt/browser! - -The browser variable WXT provides is a simple export of the browser or chrome globals provided by the browser at runtime: - - -export const browser = globalThis.browser?.runtime?.id -? globalThis.browser -: globalThis.chrome; -This means you can use the promise-style API for both MV2 and MV3, and it will work across all browsers (Chromium, Firefox, Safari, etc). - -Accessing Types -All types can be accessed via WXT's Browser namespace: - -``` -import { type Browser } from 'wxt/browser'; - -function handleMessage(message: any, sender: Browser.runtime.MessageSender) { -// ... -} -``` - -## 入口点设置 - -### 后台脚本 - -```typescript -// entrypoints/background/index.ts -import { defineBackground } from 'wxt/background'; -import { setupProxyManagement } from './proxy'; - -export default defineBackground({ - // 设置清单选项 - type: 'module', - - main() { - // 初始化代理管理 - setupProxyManagement(); - - // 监听消息 - browser.runtime.onMessage.addListener((message, sender) => { - if (message.type === 'SWITCH_PROXY') { - return handleProxySwitch(message.proxyId); - } - }); - }, -}); -``` - -### 弹出窗口 - -```html - - - -
- - -Local page for extension UI and main-world execution verification.
还没有添加任何代理
- - ), - }} - renderItem={(proxy) => ( -实时动作保存在浏览器 session;长期审计只保存脱敏摘要,不记录参数、页面内容、Cookie 或执行结果。
{action.method}{action.targetTabId ? `Tab ${action.targetTabId}` : '扩展本机'}{action.state}{action.durationMs === undefined ? '进行中' : `${action.durationMs} ms`}最近 500 条授权、Bridge、接管与能力结果。
{event.action}
+ {event.summary || (event.targetTabId ? `标签页 ${event.targetTabId}` : event.taskId ? `任务 ${event.taskId}` : '扩展本机')}
+ {AUDIT_OUTCOME_LABELS[event.outcome]}
+ {event.durationMs === undefined ? '—' : `${event.durationMs} ms`}
+ {tab?.title || '选择一个 HTTP(S) 标签页,建立浏览器现场。'}
固定代理、SOCKS、PAC 与会话级认证出口。
{draft.id}
确定性优先级、冲突预览、PAC 路由与命中统计。
{pacScript || 'function FindProxyForURL(url, host) { … }'}{state.proxyRules.find((rule) => rule.id === item.ruleId)?.name || item.ruleId}{item.hits}
)}HttpOnly、Cookie Store、CHIPS 分区与多格式交换。
{valueVisible ? cookie.value : `[hidden ${cookie.value.length}]`}{valueVisible ? 通过 Manifest V3 动态规则修改真实网络请求头,可按域名限定;不伪装页面 JS 设备指纹。
{rule.userAgent}{rule.domains.length ? rule.domains.join(', ') : '所有站点'}{rule.enabled ? '启用' : '停用'}HTTP 请求、表单导航、实时通信与前端加密调用。
生成文档绑定的结构化快照,识别认证信号并跟踪页面变化。
启用 Storage 后采集数据库与 Cache 名称。
}当前文档尚未记录 SPA 或导航变化。
}{node.tag}{node.type ? `:${node.type}` : ''}{node.nodeId}{node.disabled ? '禁用' : node.visible ? '可见' : '隐藏'}按全局路径复用页面已有的签名、加密或解密逻辑。
{result}}{JSON.stringify(evalResult.value, null, 2)}}
+ {context ? JSON.stringify(context, null, 2) : '尚未采集页面上下文。'}扩展主动连接本机 Bridge,网页无法直接访问此通道。
{bridge.engineInstanceId?.slice(0, 18)}{bridge.connectionId?.slice(0, 18)}{bridge.sessionId?.slice(0, 18)}{state.bridge.pairedEngine ? '设备身份已锁定到首次批准的 Yak 引擎。' : pairing.message}
{state.bridge.pairedEngine.engineIdentityId.slice(0, 24)}{state.bridge.pairedEngine.deviceId.slice(0, 24)}只把明确勾选的 frame 和能力授权给当前 Agent;子 frame、刷新和跨来源导航不会静默继承授权。
browser.tabs / frames列出授权标签页与完整 frame inventorybrowser.context生成结构化快照、存储 inventory、认证信号与上下文 diffbrowser.node.*检查或操作快照内的文档绑定节点引用browser.cookies读取指定标签页的浏览器 Cookiebrowser.network.*控制有界网络捕获、读取请求时间线并导出重放包browser.takeover将页面切到前台,交给用户扫码或二次验证browser.invoke以控制权限调用页面已有全局函数browser.eval以控制权限在页面主世界执行代码,支持 Promise 和超时proxy.list / switch读取并切换扩展代理配置