Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new wx send <CHAT> <MESSAGE> CLI subcommand intended for macOS that automates sending a WeChat message via osascript + keyboard-driven UI flow, and documents the new feature in the README.
Changes:
- Introduce
src/cli/send.rsimplementingcmd_send(macOS AppleScript automation + non-macOS unsupported error). - Wire
Sendinto the clap subcommand enum and dispatch insrc/cli/mod.rs. - Update
README.mdfeature list and add usage/documentation forwx send.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/cli/send.rs | New send implementation using osascript, clipboard paste, and Return-to-send; includes platform gating. |
| src/cli/mod.rs | Registers Send subcommand and dispatches to send::cmd_send. |
| README.md | Documents the new send feature and provides a usage example + macOS permission notes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if chat.trim().is_empty() { | ||
| bail!("聊天对象名称不能为空"); | ||
| } | ||
| if message.is_empty() { | ||
| bail!("消息不能为空"); | ||
| } | ||
|
|
||
| let output = Command::new("osascript") | ||
| .arg("-e") | ||
| .arg(SEND_SCRIPT) | ||
| .arg(&chat) | ||
| .arg(&message) |
There was a problem hiding this comment.
message 只用 is_empty() 校验会放过仅包含空格/换行的内容,与 PR 描述里“验证空消息”不一致。建议改为基于 message.trim() 判断空白,并(可选)像 chat 一样将 chat.trim() 的结果用于传给脚本/打印,避免用户输入前后空格导致搜索不到会话。
| if !output.status.success() { | ||
| let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string(); | ||
| let reason = if stderr.is_empty() { | ||
| format!("osascript exited with status {}", output.status) |
There was a problem hiding this comment.
当 osascript 失败且 stderr 为空时,这里会生成类似 "osascript exited with status exit status: 1" 的重复文案(ExitStatus 的 Display 已包含 "exit status:")。建议改为基于 output.status.code() 组装更清晰的错误原因,或直接格式化 output.status 而不要再额外加 "exited with status" 前缀。
| format!("osascript exited with status {}", output.status) | |
| if let Some(code) = output.status.code() { | |
| format!("osascript exited with code {}", code) | |
| } else { | |
| format!("osascript failed with status {}", output.status) | |
| } |
Summary
Adds a
wx send <CHAT> <MESSAGE>subcommand for macOS. The command activates WeChat, uses the WeChat search shortcut to open the requested chat, pastes the message into the focused input, and presses Return to send it.Motivation
Recent macOS / WeChat builds can expose only the title-bar controls through Accessibility, which makes element-based automation unreliable. This implementation avoids AX child selectors and uses the keyboard-driven search flow that was verified against the current WeChat desktop UI.
User Impact
wx send "张三" "你好"on macOS.Docs and Skill
wx sendexample, and documents the macOS/Accessibility/clipboard behavior.SKILL.mdnow teaches agents when and how to usewx send, including the requirement to get explicit user confirmation before sending a real WeChat message.Verification
cargo checkpassed.rustfmt --check src/cli/send.rspassed.osacompile.wx send --helppassed.cargo build --releasepassed.wx-cli test 2026-04-24to chat邦邦; Computer Use verified the chat opened and the message was visible.wx initcompleted,wx sessions,wx history "邦邦" -n 3, andwx search "wx-cli test" --in "邦邦" -n 5all worked.~/.codex/skills/wx-cli/SKILL.mdfor future Codex sessions.Notes
Cross-target checks were attempted but this Mac is missing the required cross C toolchains for bundled native dependencies:
cargo check --target x86_64-unknown-linux-gnufails before this crate on missingx86_64-linux-gnu-gccforlibsqlite3-sys/zstd-sys.cargo check --target x86_64-pc-windows-msvcfails before this crate on missing Windows C headers/toolchain forlibsqlite3-sys/zstd-sys.