Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ npm run daemon -- logs # 查看日志
## 前置条件

- Node.js >= 18
- macOS 或 Linux
- macOS、Windows 或 Linux
- 个人微信账号
- 已安装 [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI 并完成认证

Expand Down
2 changes: 1 addition & 1 deletion README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ The daemon long-polls WeChat for new messages, forwards them to the local `claud
## Prerequisites

- Node.js >= 18
- macOS or Linux
- macOS, Windows, or Linux
- A personal WeChat account
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI installed and authenticated

Expand Down
2 changes: 1 addition & 1 deletion SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ description: 微信消息桥接 - 在微信中与 Claude Code 聊天。支持文
## 前置条件

- Node.js >= 18
- macOS(daemon 使用 launchd 管理)
- macOS、Windows 或 Linux
- 个人微信账号(需扫码绑定)
- 已安装 Claude Code(`@anthropic-ai/claude-agent-sdk`)

Expand Down
124 changes: 123 additions & 1 deletion scripts/daemon.sh
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,114 @@ linux_logs() {
fi
}

# =============================================================================
# Windows (Git Bash / MINGW) functions
# =============================================================================

windows_pid_file() {
echo "${DATA_DIR}/${SERVICE_NAME}.pid"
}

windows_start() {
local pid_file="$(windows_pid_file)"
local node_bin="$(command -v node 2>/dev/null || echo 'node')"

if [ -f "$pid_file" ]; then
local old_pid=$(cat "$pid_file" 2>/dev/null)
if [ -n "$old_pid" ] && kill -0 "$old_pid" 2>/dev/null; then
echo "Already running (PID: $old_pid)"
exit 0
fi
rm -f "$pid_file"
fi

mkdir -p "$DATA_DIR/logs"

echo "Starting wechat-claude-code daemon (Windows)..."
nohup "$node_bin" "${PROJECT_DIR}/dist/main.js" start \
>> "$DATA_DIR/logs/stdout.log" \
2>> "$DATA_DIR/logs/stderr.log" &
local pid=$!
echo "$pid" > "$pid_file"
echo "Started (PID: $pid)"
echo "Logs: $DATA_DIR/logs/stdout.log"
}

windows_stop() {
local pid_file="$(windows_pid_file)"

if [ ! -f "$pid_file" ]; then
echo "Not running (no PID file)"
exit 0
fi

local pid=$(cat "$pid_file" 2>/dev/null)
if [ -z "$pid" ]; then
rm -f "$pid_file"
echo "Stopped"
exit 0
fi

if kill -0 "$pid" 2>/dev/null; then
kill "$pid" 2>/dev/null || true
local count=0
while kill -0 "$pid" 2>/dev/null && [ $count -lt 10 ]; do
sleep 1
count=$((count + 1))
done
# Fallback: use taskkill if process still alive
if kill -0 "$pid" 2>/dev/null; then
taskkill //F //PID "$pid" 2>/dev/null || true
fi
echo "Stopped (PID: $pid)"
else
echo "Process not running (cleaning up PID file)"
fi

rm -f "$pid_file"
}

windows_status() {
local pid_file="$(windows_pid_file)"

if [ ! -f "$pid_file" ]; then
echo "Not running"
exit 0
fi

local pid=$(cat "$pid_file" 2>/dev/null)
if [ -z "$pid" ]; then
echo "Not running (invalid PID file)"
exit 0
fi

if kill -0 "$pid" 2>/dev/null; then
echo "Running (PID: $pid)"
else
echo "Not running (stale PID file)"
fi
}

windows_logs() {
local log_dir="${DATA_DIR}/logs"
if [ -d "$log_dir" ]; then
local latest=$(ls -t "${log_dir}"/bridge-*.log 2>/dev/null | head -1)
if [ -n "$latest" ]; then
tail -100 "$latest"
else
for f in "${log_dir}"/stdout.log "${log_dir}"/stderr.log; do
if [ -f "$f" ]; then
echo "=== $(basename "$f") ==="
tail -50 "$f"
echo ""
fi
done
fi
else
echo "No logs found"
fi
}

# =============================================================================
# Main dispatcher
# =============================================================================
Expand Down Expand Up @@ -411,9 +519,23 @@ main() {
;;
esac
;;
MINGW*|MSYS*|CYGWIN*)
case "$command" in
start) windows_start ;;
stop) windows_stop ;;
restart) windows_stop; sleep 1; windows_start ;;
status) windows_status ;;
logs) windows_logs ;;
*)
echo "Usage: daemon.sh {start|stop|restart|status|logs}"
echo "Platform: Windows (Git Bash)"
exit 1
;;
esac
;;
*)
echo "Error: Unsupported platform '$OS_TYPE'"
echo "Supported platforms: macOS (Darwin), Linux"
echo "Supported platforms: macOS (Darwin), Linux, Windows (MINGW/MSYS)"
exit 1
;;
esac
Expand Down
7 changes: 6 additions & 1 deletion src/tools/visualize-logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,12 @@ function main() {
writeFileSync(output, html, 'utf-8');
console.log(`Written to: ${output}`);
if (open) {
execSync(`open "${output}"`);
const cmd = process.platform === 'win32'
? `cmd /c start "" "${output}"`
: process.platform === 'darwin'
? `open "${output}"`
: `xdg-open "${output}"`;
execSync(cmd);
}
} else {
process.stdout.write(html);
Expand Down
3 changes: 2 additions & 1 deletion src/wechat/send.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { existsSync } from 'node:fs';
import { homedir } from 'node:os';
import { resolve } from 'node:path';
import { WeChatApi } from './api.js';
import { MessageItemType, MessageType, MessageState, TypingStatus, type MessageItem, type OutboundMessage } from './types.js';
Expand Down Expand Up @@ -115,7 +116,7 @@ export function createSender(api: WeChatApi, botAccountId: string) {
}

async function sendFile(toUserId: string, contextToken: string, filePath: string): Promise<void> {
const resolved = resolve(filePath.replace(/^~/, process.env.HOME || ''));
const resolved = resolve(filePath.replace(/^~/, homedir()));
if (!existsSync(resolved)) {
await sendText(toUserId, contextToken, `文件不存在: ${resolved}`);
return;
Expand Down