尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
AionUi E2E 测试全指南:基于 Playwright 的 Electron 桌面端端到端测试架构与实战
AionUi E2E 测试全指南基于 Playwright 的 Electron 桌面端端到端测试架构与实战【免费下载链接】AionUiOpen-source 24/7 Cowork app for OpenClaw, Hermes, Claude Code, Codex, OpenCode and 20 more CLI Agent | Customize your assistants | Team them upStar if you like it!项目地址: https://gitcode.com/GitHub_Trending/ai/AionUi导读AionUi 是面向多 CLI AgentOpenClaw、Claude Code、Codex 等 20的 24/7 协作桌面应用其桌面端核心逻辑全部运行在 Electron 主进程与 Renderer 进程中。为了让整个应用启动、导航、会话、团队协作、扩展系统经受真实用户操作级别的验证仓库在 tests/e2e 目录下搭建了一套完整的 Playwright Electron 端到端测试体系。本文以 tests/e2e/README.md 为骨架结合仓库中 playwright.config.ts、tests/e2e/fixtures.ts 以及 helpers 层源码完整讲解这套体系的构建方式、运行流程、编写规范与排障手段。读完本文你将能够在本仓库中完成 E2E 环境的搭建、编写稳定可复用的端到端用例并定位测试失败的根本原因。一、快速开始从构建到运行的最小路径1. 先构建应用E2E 加载的是静态产物与许多使用 Vite dev server 热更新的项目不同AionUi 的 E2E 测试直接通过electron .启动 Electron加载的是out/目录下的预构建文件。因此任何源码改动都必须先重新构建测试才能感知到新代码。# 完整构建main preload renderer bunx electron-vite build这里需要区分两个概念bun run start即electron-vite dev走的是 Vite HMR会自动热更新但仅供开发调试使用E2E 测试不使用 Vite dev server它们加载的是out/下的静态文件。构建命令来自仓库根目录 package.json通过bunx electron-vite build调用packages/desktop下的 electron-vite 配置 electron.vite.config.ts。产物结构为out/main/index.js、out/preload/*.js与out/renderer/index.html这一布局与 tests/e2e/fixtures.ts 中描述的两种启动模式完全对应。2. 确保aioncore后端二进制在 PATH 上AionUi 的架构是「Electron 壳 独立后端进程」Electron 主进程在启动时会 spawn 名为aioncore的后端二进制并将其端口通过window.__backendPort暴露给 Renderer。二进制的定位依赖which aioncore因此它必须能从 Playwright runner 继承的PATH中找到。如果找不到__backendPort会是0Renderer 以及使用 tests/e2e/helpers/httpBridge.ts 的 E2E helpers 发起的每一次 HTTP 调用都会以Failed to fetch失败。# 安装后端二进制构建到 ~/.cargo/bin/aioncore cd ../AionCore cargo install --path crates/aionui-app # 运行测试前确保它在 PATH 上 export PATH$HOME/.cargo/bin:$PATH从源码结构看aioncore是独立于本仓库的 AionCore 仓库中的 Rust 应用crates/aionui-app本仓库的 packages/web-host 与 scripts/prepareAioncore.js 等脚本负责其下载与准备测试环境的aioncore则由 CI 或本地手工构建提供。3. 运行测试# 运行全部 E2E 测试 bun run test:e2e # 运行单个测试文件指定配置文件与 reporter npx playwright test --config playwright.config.ts tests/e2e/specs/team-workspace-migration.e2e.ts --reporterlist注意README 中给出的单文件示例指向tests/e2e/specs/team-workspace-migration.e2e.ts而从当前仓库 package.json 与tests/e2e/specs/目录来看团队相关用例已迁移至tests/e2e/cases/teams/下specs/目录当前实际包含的是app-launch.e2e.ts、assistant-settings-*.e2e.ts、ext-*.e2e.ts、feedback-*.e2e.ts等 50 个用例文件。运行时请以仓库实际存在的路径为准。4. 查看测试结果# 打开 HTML 报告 npx playwright show-report tests/e2e/report截图screenshots、trace 和视频videos保存在tests/e2e/results/目录由 playwright.config.ts 的outputDir指定。失败用例的截图还会通过自定义 fixture 自动附加到 HTML 报告见下文「fixture 设计」。二、架构单一 Electron 实例的复用模型应用生命周期Playwright 启动 Electron 应用每个 worker 单例 → 应用加载 out/main/index.js → 主进程创建 BrowserWindow → Renderer 加载 out/renderer/index.htmlHashRouter → 测试与 renderer 页面交互 → 应用在整个测试文件中保持存活describe 之间不重启 → worker 退出时应用关闭关键设计决策所有测试共享同一个 Electron 实例。原因是重启一次 Electron 需要约 25~30 秒如果每个 describe 都重启测试总时长将不可接受。这一决策直接体现在 tests/e2e/fixtures.ts 的实现中模块级单例let app: ElectronApplication | null与let mainPage: Page | null每个测试 worker 只启动一次应用tests/e2e/fixtures.ts刻意不用test.afterAll做清理——Playwright 会在每个describe 块结束时执行 afterAll那样会在 describe 之间反复关闭/重启 Electron。取而代之的是注册一次性process.on(beforeExit)处理器让单例应用存活整个 worker 生命周期tests/e2e/fixtures.tsplaywright.config.ts中workers: 1、fullyParallel: false注释明确写着「Must be 1: tests share a singleton Electron app instance」playwright.config.ts。此外 fixture 还做了进程守护每次获取electronApp时先app.evaluate(() true)探测进程是否存活若崩溃则自动重新启动并重新解析主窗口tests/e2e/fixtures.ts。两种启动模式模式触发条件运行内容适用场景Dev本地默认E2E_DEV1或不设置环境变量从项目根目录electron .本地开发PackagedCI 默认E2E_PACKAGED1或 CI 环境out/下构建好的应用CI 流水线两种模式都加载out/下的预构建文件差异在于 Packaged 模式使用NODE_ENVproduction以及平台特定的可执行文件。对应实现位于 tests/e2e/fixtures.tsshouldUsePackagedMode()E2E_PACKAGED1优先其次E2E_DEV1默认!!process.env.CIresolvePackagedApp()在out/下按平台查找可执行文件——Windows 找win-unpacked/AionUi.exemacOS 找mac-arm64/AionUi.app/Contents/MacOS/AionUiLinux 找linux-unpacked/aionui。找不到时抛错提示先运行node scripts/build-with-builder.js auto --platform --pack-onlyLinux CI 环境会自动追加--no-sandbox启动参数环境变量注入见 tests/e2e/fixtures.ts包括AIONUI_EXTENSIONS_PATH指向仓库examples/目录使扩展用例可运行、临时AIONUI_EXTENSION_STATES_FILE、临时AIONUI_E2E_USER_DATA_DIR每次运行用fs.mkdtempSync创建一次性 userData 目录避免污染开发者真实数据库见 tests/e2e/fixtures.ts。目录结构tests/e2e/ ├── fixtures.ts # Electron 启动、page fixture、单例管理 ├── helpers/ │ ├── index.ts # 统一 re-export 全部 helpers │ ├── bridge/ │ │ ├── invoke.ts # invokeBridge()——与主进程 IPC 通信HTTP 优先 IPC 兜底 │ │ ├── routes.ts # bridge key → 后端 HTTP 路由映射 │ │ └── mappers.ts # 响应数据映射 │ ├── navigation.ts # 路由 helpersnavigateTo、goToGuid、goToSettings │ ├── conversation.ts # 会话 helperssendMessage、waitForAiReply、selectAgent │ ├── httpBridge.ts # 基于 fetch 的后端 HTTP 调用httpGet/httpPost/httpDelete │ ├── selectors.ts # UI 元素 CSS 选择器 │ ├── assertions.ts # 自定义断言expectBodyContainsAny、错误收集器 │ ├── extensions.ts # 扩展快照 helpers │ ├── assistantSettings.ts # Assistant CRUD helpers │ ├── teamConfig.ts # TEAM_SUPPORTED_BACKENDS 白名单 │ ├── teamHelpers.ts # 团队创建/清理 helpers │ ├── chatAionrs.ts # AionRS 后端会话 helpers │ ├── permissions.ts # MCP 权限弹窗自动批准 │ ├── monitorEvents.ts # 事件监控记录器 │ └── screenshots.ts # 手动截图 helper ├── specs/ # 50 个 *.e2e.ts 用例文件 ├── cases/teams/ # 团队专项用例team-create / team-agent-lifecycle 等 ├── results/ # 测试产物gitignored ├── report/ # HTML 报告gitignored └── screenshots/ # 手动截图gitignored与 README 中的结构图相比实际仓库将bridge.ts演进为bridge/子目录invoke.tsroutes.tsmappers.ts并将团队用例迁移到了cases/teams/下导航、会话等核心 helpers 保持不变。helpers 的统一出口在 tests/e2e/helpers/index.ts新增用例只需import { invokeBridge, navigateTo } from ../helpers。三、编写测试基础模式与核心 Helpers基础模式import { test, expect } from ../fixtures; import { invokeBridge, navigateTo } from ../helpers; test.describe(Feature Name, () { test(what it should do, async ({ page, electronApp }) { // 1. 导航 await navigateTo(page, #/some-route); // 2. 交互 const input page.locator(textarea).first(); await input.fill(Hello); await input.press(Enter); // 3. 断言 UI await expect(page.locator(textHello)).toBeVisible({ timeout: 10_000 }); // 4. 断言后端可选 const data await invokeBridge(page, some.bridge-key, { param: value }); expect(data.field).toBe(expected); }); });注意这里的test与expect均来自../fixtures即 tests/e2e/fixtures.ts而非直接来自playwright/test——这是拿到electronApp与共享pagefixture 的前提。核心 Helpers 一览Helper用途导入来源invokeBridge(page, key, data)调用主进程 / 后端桥接能力../helpersnavigateTo(page, hash)通过侧边栏 UI 导航../helperswaitForAiReply(page)等待 AI 回复自动穿透 Shadow DOM../helpersselectAgent(page, backend)为某个后端选择可用的 assistant../helperssendMessageFromGuid(page, msg)发送消息并返回 conversation ID../helpersdeleteConversation(page, id)按 ID 删除会话清理用../helpersMODE_SELECTOR模式选择胶囊[data-testidmode-selector]../helpersmodeMenuItemByValue(value)模式下拉项[data-mode-value...]../helpers除 README 列出的这些外tests/e2e/helpers/index.ts 还 re-export 了httpInvoke/httpGet/httpPost/httpDelete、runConversationCycle、waitForSessionActive、createTeam/ensureTeam/deleteTeam/cleanupTeamsByName、startAutoApprovePermissionMessages以及一整套 assistant 设置 CRUD helpers覆盖了团队、扩展、Assistant 设置、AionRS 会话等全部测试域。navigateTo 的实现细节导航 helper 之所以重要是因为该应用使用 HashRouter ProtectedLayout在 React Router 尚未初始化时直接用window.location.assign是不可靠的。因此 tests/e2e/helpers/navigation.ts 采用「像用户一样点击」的策略离开设置页点击.sider-footer div侧边栏按钮进入设置子页先点侧边栏进入设置再点击[data-settings-path...]导航项使用isAlreadyAt()检测是否已在目标 hash避免连续用例重复渲染导航前先ensureRendererReady()等待window.__backendPort变为 numbertests/e2e/helpers/navigation.ts导航后等待document.body.textContent超过 50 字符作为页面有实际内容的信号。invokeBridge 的双通道实现README 中的invokeBridge(page, key, data)是 E2E 与后端能力交互的核心其现代实现位于 tests/e2e/helpers/bridge/invoke.ts采用「HTTP 优先 IPC 兜底」的双通道策略优先路径查HTTP_ROUTES[key]路由表若命中则把 bridge key 映射为后端 HTTP 路由从 Renderer 上下文发起fetch(http://127.0.0.1:__backendPortpath)——与运行中的应用访问 aioncore 的方式完全一致兜底路径对路由表中不存在的 key退回桌面 IPC 协议emit(subscribe-{key}, { id, data })→ 监听subscribe.callback-{key}{id}超时抛Bridge invoke timeout: {key}这就是排障章节该报错信息的代码出处。invokeBridge 使用规则允许禁止**Setup**读取初始状态team.list、team.get触发操作添加成员、发送消息**Assert**验证后端与 UI 一致操作必须走 UI 交互**Cleanup**删除测试数据team.remove这条规则是整个 E2E 体系「贴近真实用户」原则的体现bridge 只用于观测与清理业务操作必须经由 UI 元素触发否则测试验证的就只是代码路径而非用户路径。超时指南操作超时UI 元素可见性5,000 - 15,000ms导航 页面稳定10,000msAI 回复单模型120,000ms团队操作leader 推断 MCP60,000 - 120,000ms成员初始化60,000ms从 playwright.config.ts 看全局timeout: 60_000、expect.timeout: 10_000但 AI 推理类断言会显式传入更长的 timeout如 tests/e2e/helpers/conversation.ts 中waitForSessionActive默认 120 秒runConversationCycle则放宽到 180 秒。四、高级技巧Shadow DOM、原生对话框与截图Mock 原生对话框Electron当测试涉及文件选择等原生对话框时可直接在 Electron 主进程上下文覆写dialogAPI// Mock 文件打开对话框 await electronApp.evaluate(async ({ dialog }, targetPath) { dialog.showOpenDialog () Promise.resolve({ canceled: false, filePaths: [targetPath] }); }, /path/to/target);electronApp.evaluate运行在主进程上下文是 Playwright Electron 支持的原生能力。Shadow DOM 穿透AI 消息文本渲染在 Shadow DOM.markdown-shadow内部。普通textContent/innerText拿不到宿主元素内的影子内容必须穿透 shadowRoot。日常推荐直接使用waitForAiReply()它内部已经处理了穿透逻辑tests/e2e/helpers/conversation.tsconst text await page.evaluate(() { const el document.querySelector(.message-item.text.justify-start:last-child); const shadow el?.querySelector(.markdown-shadow); return shadow?.shadowRoot?.textContent?.trim() ?? ; });判定「AI 是否回复」的核心信号是出现左对齐的.message-item.text.justify-start右对齐是用户消息且其 Shadow DOM 内存在非空文本。waitForSessionActive还提供了.agent-status-message徽标作为辅助信号——但徽标只短暂出现因此主信号始终是 AI 回复文本本身tests/e2e/helpers/conversation.ts。截图// 手动截图保存到 tests/e2e/results/ await page.screenshot({ path: tests/e2e/results/my-step.png });失败用例自动附加截图到 HTML 报告。由于自定义 fixture 覆盖了 Playwright 内置pagefixture内置的screenshot: only-on-failure不再生效因此 tests/e2e/fixtures.ts 在pagefixture 的 teardown 阶段手动实现用例状态与预期不符时调用mainPage.screenshot()并testInfo.attach(screenshot-on-failure, ...)确保失败截图进入报告。稳定性工程错误诊断与轮询fixtures 还内建了「失败归因」能力tests/e2e/fixtures.tsattachRendererDiagnostics采集 renderer 的 console error/warning、pageerror、requestfailed存入 WeakMapensureRendererAppMounted等待#root出现非空子节点且存在 script若 30 秒内未挂载则输出完整快照URL、title、readyState、body 长度、脚本/样式表列表与最近 20 条诊断信息后抛错。这样当「应用启动但页面空白」时报错信息里直接携带现场快照不用二次排查。五、环境变量与 NPM Scripts用户可控环境变量变量默认值用途E2E_PACKAGED1未设置dev 模式使用out/下的打包应用E2E_DEV1未设置强制 dev 模式TEAM_AGENTallclaude,codex,gemini过滤团队 leader 类型CI未设置自动选择 packaged 模式启动时自动注入的环境变量变量值用途AIONUI_E2E_TEST1应用识别测试模式AIONUI_DISABLE_AUTO_UPDATE1禁止更新检查AIONUI_DISABLE_DEVTOOLS1不打开 DevTools 窗口AIONUI_CDP_PORT9230CDP 单目标通道端口其中AIONUI_CDP_PORT值得展开它曾长期设为0彻底关闭 CDP因为当时开启 CDP 等于开启 Chromium 应用级 remote-debugging-port会把每个 WebContents 无认证暴露且多实例间会争抢固定端口。如今改成了「系统随机分配端口 必须带口令连接」的单目标通道风险消除继续关闭它反而意味着这套安全属性在 E2E 中永远测不到——测试会静默 skip、看起来像通过相关注释见 tests/e2e/fixtures.ts。除 README 列出的四项外fixtures 还会注入AIONUI_EXTENSIONS_PATH指向examples/、AIONUI_EXTENSION_STATES_FILE与AIONUI_E2E_USER_DATA_DIR均为一次性临时目录。NPM Scripts命令范围bun run test:e2e全部 E2E 测试bun run test:e2e:team全部cases/teams/*.e2e.tsbun run test:e2e:team:create仅团队创建bun run test:e2e:team:lifecycle添加 触发成员bun run test:e2e:team:whitelistAgent 白名单下拉bun run test:e2e:team:comm消息发送以上脚本定义在仓库根目录 package.json注意团队脚本实际匹配的是tests/e2e/cases/teams/*.e2e.tsREADME 的team-*.e2e.ts表述对应用例迁移后的目录。组合示例# 本地运行全部 E2Edev 模式需先构建 bunx electron-vite build bun run test:e2e # 只跑团队测试使用 list reporter bun run test:e2e:team # 运行单个测试文件 npx playwright test --config playwright.config.ts tests/e2e/specs/app-launch.e2e.ts # 只测试 gemini leader 类型 TEAM_AGENTgemini bun run test:e2e:team # 以 packaged 模式运行模拟 CI E2E_PACKAGED1 bun run test:e2ereporter 与 trace 的 CI 差异化配置见 playwright.config.tsCI 使用githubreporter HTML 报告本地使用list HTML 报告E2E_TRACE1时 trace/video 保留到失败否则仅首次重试时保留。六、故障排查手册测试出现旧 UI / 旧行为原因源码改动后未重新构建。bunx electron-vite buildE2E 加载的是out/静态产物这一条贯穿始终。Bridge invoke timeout: xxx原因key 对应的 IPC provider 不存在或未注册。检查路由映射tests/e2e/helpers/bridge/routes.ts中是否定义了该 key若走 IPC 兜底路径检查对应 bridge 文件的.provider()注册如src/process/bridge/teamBridge.ts该路径为 README 所述实际实现可搜索src/process/bridge/下同名文件重新构建bunx electron-vite build。应用启动了但页面空白原因renderer 构建缺失或损坏。bunx electron-vite build若问题依旧tests/e2e/fixtures.ts 的ensureRendererAppMounted会输出页面快照与 renderer 诊断信息可据此判断是脚本加载失败、请求失败还是 React 挂载异常。AI 回复相关测试不稳定增大超时AI 推理耗时随负载波动用expect.poll()替代固定的waitForTimeout()——轮询直到条件成立而非盲等为 MCP 确认弹窗添加重试逻辑参考autoApproveMcpDialogs模式仓库中对应 tests/e2e/helpers/permissions.ts 的startAutoApprovePermissionMessages/waitForPermissionMessageCard。侧边栏残留测试数据方式一直接清理数据库示例为 macOS 路径实际取决于系统与AIONUI_E2E_USER_DATA_DIR覆盖情况sqlite3 ~/Library/Application Support/AionUi-Dev/aionui/aionui.db \ DELETE FROM teams WHERE name LIKE E2E%;方式二在测试开头通过 bridge 做清理更推荐且与「Cleanup 走 bridge」的规则一致const teams await invokeBridge(page, team.list, { userId: system_default_user }); for (const t of teams) { if (t.name.startsWith(E2E)) { await invokeBridge(page, team.remove, { id: t.id }).catch(() {}); } }仓库中的cleanupTeamsByNametests/e2e/helpers/teamHelpers.ts正是这类清理逻辑的封装可优先复用。七、源码级延伸这套体系如何与桌面端架构呼应E2E 体系不是孤立的测试代码它精确映射了 AionUi 桌面端的三层架构window.__backendPort机制由 preload 脚本packages/desktop/src/preload 下README 与 tests/e2e/helpers/httpBridge.ts 均注明src/preload/main.ts暴露该端口把后端端口注入 rendererE2E 的 HTTP helpers 与运行中的应用走完全相同的通道——同一端口、同一 base URL、同一响应解包逻辑{ success, data }包裹结构单例复用 一次性 userData应用不重启换来了速度一次性 userData 目录则换来隔离性——每次运行都用临时目录让 AionCore 迁移全新数据库既避免共享数据库迁移失败阻塞整个应用启动也保护开发者的真实数据HashRouter 路由导航 helpers 全部围绕 hash 路由#/guid、#/settings/assistants等常量定义于 tests/e2e/helpers/navigation.ts设计navigateTo的「像用户一样点击」策略正是对「ProtectedLayout 未就绪时编程式跳转不可靠」这一架构事实的回应。对于想深入了解编写风格与断言模式的读者仓库提供了丰富样本tests/e2e/specs/app-launch.e2e.ts应用启动与渲染、tests/e2e/specs/conversation-full-cycle.e2e.ts完整会话周期、tests/e2e/cases/teams/下的团队用例tests/e2e/specs/README.md 记录了团队 E2E 的编写规则以及 tests/e2e/specs/ext-lifecycle.e2e.ts扩展生命周期。结合 playwright.config.ts 与 tests/e2e/fixtures.ts 阅读即可完整理解这套「快、稳、可诊断」的桌面端 E2E 体系。【免费下载链接】AionUiOpen-source 24/7 Cowork app for OpenClaw, Hermes, Claude Code, Codex, OpenCode and 20 more CLI Agent | Customize your assistants | Team them upStar if you like it!项目地址: https://gitcode.com/GitHub_Trending/ai/AionUi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

【记录】RedisUtil踩坑记录(redis过期时间问题)

【记录】RedisUtil踩坑记录(redis过期时间问题)

Redis中Java设置超时时间的常用方法——expire()。spring-boot-common的RedisUtil和此处的Jedis同理。它可以用于设置键的超时时间,以秒为单位。expire()可以将任何Redis中Java保存的值以秒为单位设置超时时间。例如,下面的代码可以实现将缓存值设置为超…

📅 2026/9/10 9:24:50
WorkBuddy实战:P0故障复盘从3小时缩短到40分钟

WorkBuddy实战:P0故障复盘从3小时缩短到40分钟

如果你做过几年线上服务的故障值班,应该对这种凌晨并不陌生:告警蜂鸣、群里一片问号、临时拉起排查群,一帮人边界不清地对着日志平台刷关键字。等真正定位完问题,天也亮了,然后还要再花两三个小时写一份复盘&#xff0…

📅 2026/9/10 9:19:49
CC Switch:本地大模型路由代理与Codex兼容性原理

CC Switch:本地大模型路由代理与Codex兼容性原理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/10 9:19:49
MORE NEWS

更多资讯

📰

3分钟跑通 MCP Toolbox:把数据库安全接入 AI 智能体的完整指南

3分钟跑通 MCP Toolbox:把数据库安全接入 AI 智能体的完整指南 【免费下载链接】mcp-toolbox MCP Toolbox for Databases is an open source MCP server for databases. 项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox MCP Toolbox for Data…

📰

静态评测Quackd:多具身机器人安全任务编排架构与隐患分析

最近在开源机器人社区里闲逛的时候,注意到一个叫Quackd的项目,定位是“面向多具身机器人系统的高层安全任务编排器”。多机器人协作这几年很火,但大多数项目都集中在底层控制或者单体智能上,真正把“任务编排”和“安全约束”放在…

📰

Gradio 前端 Tooltip 组件解析:@gradio/tooltip 的源码实现与版本演进

Gradio 前端 Tooltip 组件解析:gradio/tooltip 的源码实现与版本演进 【免费下载链接】gradio Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work! 项目地址: https://gitcode.com/GitHub_Trending/gr/g…

📰

U-Net++多任务学习实现IDC病理图像定位与分级

简介:本资源是一套面向医学图像分析初学者与AI医疗实践者的完整深度学习项目,基于Python实现IDC乳腺癌病理图像的恶性区域像素级识别与肿瘤侵袭性分级。项目采用卷积神经网络模型,可自动定位原始病理切片中带恶性病灶的像素区域,并…

📰

3 分钟本地解锁 WeMod 专业版:Wand-Enhancer 完整补丁指南

3 分钟本地解锁 WeMod 专业版:Wand-Enhancer 完整补丁指南 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/GitHub_Trending/we/Wand-Enhancer 打开 Wand(WeMod…

📰

OmniRoute 发布检查清单实践:版本同步守卫、Node 运行时安全基线与 npm 产物校验

OmniRoute 发布检查清单实践:版本同步守卫、Node 运行时安全基线与 npm 产物校验 【免费下载链接】OmniRoute Never stop coding. Free MIT AI gateway: one endpoint, 352 providers (150 free), 1200 models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬