mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-10 00:10:46 +08:00
收敛微信 sidecar 到官方单链路并同步文档与回归测试。
移除 weixin 安装与启动脚本中的 legacy/localSource 分支,只保留 official_runner 路径,统一开源安装命令并更新 RUNBOOK/Quickstart/README,确保脚本行为与测试预期一致。 Made-with: Cursor
This commit is contained in:
parent
3122b8a16c
commit
853dc1812f
7 changed files with 43 additions and 116 deletions
|
|
@ -33,13 +33,13 @@ powershell -ExecutionPolicy Bypass -File .\scripts\stop_gateway.ps1 -Force
|
|||
### 3) Weixin (Personal WeChat): install → login → start
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\runtime\operations\scripts\weixin_install.ps1 -UseOpenclawCli
|
||||
powershell -ExecutionPolicy Bypass -File .\runtime\operations\scripts\weixin_install.ps1
|
||||
powershell -ExecutionPolicy Bypass -File .\runtime\operations\scripts\weixin_login.ps1
|
||||
powershell -ExecutionPolicy Bypass -File .\runtime\operations\scripts\weixin_start.ps1
|
||||
```
|
||||
|
||||
Notes:
|
||||
- `weixin_install.ps1 -UseOpenclawCli` does **not** require global `openclaw` CLI installation; runtime deps are installed locally in sidecar workspace.
|
||||
- `weixin_install.ps1` does **not** require global `openclaw` CLI installation; runtime deps are installed locally in sidecar workspace.
|
||||
- `.\scripts\start_all.ps1 -Background` now skips missing Weixin/WhatsApp sidecars gracefully (warn + continue), so Admin/Chat can still boot on fresh installs.
|
||||
- Admin supports channel dispatch controls for Weixin/WhatsApp (bind specialist / comprehensive), with default `generalist`.
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ Notes:
|
|||
## Path B: Enable Weixin (Personal WeChat)
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\runtime\operations\scripts\weixin_install.ps1 -UseOpenclawCli
|
||||
powershell -ExecutionPolicy Bypass -File .\runtime\operations\scripts\weixin_install.ps1
|
||||
powershell -ExecutionPolicy Bypass -File .\runtime\operations\scripts\weixin_login.ps1
|
||||
powershell -ExecutionPolicy Bypass -File .\runtime\operations\scripts\weixin_start.ps1
|
||||
```
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ powershell -ExecutionPolicy Bypass -File .\scripts\stop_gateway.ps1 -Force
|
|||
> 这一步会安装/更新官方插件到:`%USERPROFILE%\.openclaw\extensions\openclaw-weixin\`
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\runtime\operations\scripts\weixin_install.ps1 -UseOpenclawCli
|
||||
powershell -ExecutionPolicy Bypass -File .\runtime\operations\scripts\weixin_install.ps1
|
||||
```
|
||||
|
||||
### 1.1.5 扫码登录(绑定账号)
|
||||
|
|
@ -89,8 +89,8 @@ powershell -ExecutionPolicy Bypass -File .\runtime\operations\scripts\weixin_log
|
|||
|
||||
按提示扫码完成绑定(会写入账号 ID / token 等状态到 `%USERPROFILE%\.openclaw\openclaw-weixin\`)。
|
||||
|
||||
> 说明:这里的 `-UseOpenclawCli` **不要求你全局安装 openclaw**(不需要 `npm install -g openclaw`)。
|
||||
> 脚本会在 `data/channel_sidecar/oclaw-weixin/` 下本地安装 `openclaw` npm 包,并用 `npx openclaw ...` 驱动官方插件完成扫码与状态写入。
|
||||
> 说明:`weixin_install.ps1` **不要求你全局安装 openclaw**(不需要 `npm install -g openclaw`)。
|
||||
> 脚本会在 `data/channel_sidecar/oclaw-weixin/` 下安装本地运行时依赖,并完成官方插件安装。
|
||||
|
||||
### 1.1.6 启动微信 sidecar(原生模式)
|
||||
|
||||
|
|
@ -114,7 +114,7 @@ powershell -ExecutionPolicy Bypass -File .\runtime\operations\scripts\weixin_sta
|
|||
- **启动网关提示端口占用 / 你以为重启了但没生效**
|
||||
- 用 `stop_gateway.ps1 -Force` 强制按端口清理旧监听进程,然后再启动。
|
||||
- **Node 版本不对**
|
||||
- 官方插件要求 `node >=22`;请升级 Node 后重新执行 `weixin_install.ps1 -UseOpenclawCli`。
|
||||
- 官方插件要求 `node >=22`;请升级 Node 后重新执行 `weixin_install.ps1`。
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -222,17 +222,15 @@ Linux/macOS:
|
|||
- 本仓库宿主适配负责:
|
||||
- 把官方入站消息转换成 `oclaw` 可消费的本地 payload
|
||||
- 通过本地 `/weixin/native/reply` 同步生成回复
|
||||
- 保留一个历史 `runner.ts` fallback,便于短期回滚
|
||||
|
||||
对应脚本行为:
|
||||
|
||||
- `runtime/operations/scripts/weixin_install.ps1 -UseOpenclawCli`
|
||||
- `runtime/operations/scripts/weixin_install.ps1`
|
||||
- 安装官方 `openclaw-weixin` 插件
|
||||
- 安装运行官方模块所需的本地 Node 依赖
|
||||
- 同步 `runtime/operations/weixin_bridge/official_runner.ts` / `runner.ts` / `login.ts`
|
||||
- 同步 `runtime/operations/weixin_bridge/official_runner.ts` / `login.ts`
|
||||
- `runtime/operations/scripts/weixin_start.ps1`
|
||||
- 默认启动 `official_runner.ts`
|
||||
- 设置 `AIA_WEIXIN_RUNNER_MODE=legacy` 时,临时回退到历史 `runner.ts`
|
||||
- 仅启动 `official_runner.ts`(官方单链路)
|
||||
|
||||
现阶段主路径建议:
|
||||
|
||||
|
|
@ -549,25 +547,7 @@ npm install images-mcp
|
|||
powershell -ExecutionPolicy Bypass -File .\scripts\weixin_install.ps1
|
||||
```
|
||||
|
||||
注意:
|
||||
|
||||
- 脚本支持两种模式:
|
||||
- 官方插件模式:`-UseOpenclawCli`(不校验 `runner.ts/login.ts`)
|
||||
- 本地 sidecar 模式:`-LocalSourcePath`(会强校验 `runner.ts/login.ts`)
|
||||
|
||||
- 默认按本地 sidecar 模式处理:必须传 `-LocalSourcePath`(指向你们自研 weixin sidecar 源码目录)。
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\scripts\weixin_install.ps1 -LocalSourcePath "D:\path\to\your-weixin-module"
|
||||
```
|
||||
|
||||
- 若你要临时切回官方链路,可显式指定:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\scripts\weixin_install.ps1 -UseOpenclawCli
|
||||
```
|
||||
|
||||
- 仅本地 sidecar 模式会强校验 `runner.ts` / `login.ts` 是否存在;官方插件模式不做该校验。
|
||||
注意:当前仅保留官方插件单链路,直接执行 `weixin_install.ps1` 即可。
|
||||
|
||||
安装目录:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
param(
|
||||
[string]$ChannelId = "oclaw-weixin",
|
||||
[string]$LocalSourcePath = "",
|
||||
[switch]$UseOpenclawCli = $false
|
||||
[string]$ChannelId = "oclaw-weixin"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
|
@ -16,6 +14,16 @@ $oclawRoot = Resolve-RepoRoot
|
|||
$sidecarRoot = Join-Path $oclawRoot "data\\channel_sidecar\\$ChannelId"
|
||||
$stateDir = Join-Path $sidecarRoot "state"
|
||||
$pluginRoot = Join-Path $env:USERPROFILE ".openclaw\\extensions\\openclaw-weixin"
|
||||
function Sync-WeixinBridgeRunners {
|
||||
$bridgeSrc = Join-Path $oclawRoot "runtime\\operations\\weixin_bridge"
|
||||
foreach ($name in @("official_runner.ts", "login.ts")) {
|
||||
$srcPath = Join-Path $bridgeSrc $name
|
||||
if (-not (Test-Path $srcPath)) {
|
||||
throw "missing bridge source file: $srcPath"
|
||||
}
|
||||
Copy-Item -Path $srcPath -Destination (Join-Path $sidecarRoot $name) -Force
|
||||
}
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $sidecarRoot | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path (Join-Path $sidecarRoot "logs") | Out-Null
|
||||
|
|
@ -36,52 +44,6 @@ function Ensure-OfficialPluginRuntimeDeps {
|
|||
}
|
||||
}
|
||||
|
||||
if ($UseOpenclawCli) {
|
||||
# Do not require a globally-installed openclaw CLI.
|
||||
# We install openclaw into the sidecar runtime and put node_modules/.bin on PATH
|
||||
# so the official installer can run `openclaw ...` commands.
|
||||
Push-Location $sidecarRoot
|
||||
try {
|
||||
if (-not (Test-Path (Join-Path $sidecarRoot "package.json"))) {
|
||||
npm.cmd init -y | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "npm init failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
}
|
||||
npm.cmd install openclaw@latest --save
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "npm install openclaw failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
$env:PATH = (Join-Path $sidecarRoot "node_modules\\.bin") + ";" + $env:PATH
|
||||
npx.cmd -y @tencent-weixin/openclaw-weixin-cli@latest install
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "openclaw-weixin-cli install failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
Ensure-OfficialPluginRuntimeDeps
|
||||
Push-Location $sidecarRoot
|
||||
try {
|
||||
npm.cmd install openclaw@latest --save tsx@4.21.0 typescript@6.0.3
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "npm install bridge runtime deps failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
$bridgeSrc = Join-Path $oclawRoot "runtime\\operations\\weixin_bridge"
|
||||
Copy-Item -Path (Join-Path $bridgeSrc "runner.ts") -Destination (Join-Path $sidecarRoot "runner.ts") -Force
|
||||
Copy-Item -Path (Join-Path $bridgeSrc "official_runner.ts") -Destination (Join-Path $sidecarRoot "official_runner.ts") -Force
|
||||
Copy-Item -Path (Join-Path $bridgeSrc "login.ts") -Destination (Join-Path $sidecarRoot "login.ts") -Force
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
Write-Host "[ok] installed official openclaw-weixin plugin + native/fallback sidecar runtime"
|
||||
exit 0
|
||||
}
|
||||
|
||||
if (-not $LocalSourcePath) {
|
||||
throw "LocalSourcePath is required in sidecar mode. Example: .\\scripts\\weixin_install.ps1 -LocalSourcePath D:\\path\\to\\your-weixin-module"
|
||||
}
|
||||
|
||||
Push-Location $sidecarRoot
|
||||
try {
|
||||
if (-not (Test-Path (Join-Path $sidecarRoot "package.json"))) {
|
||||
|
|
@ -90,21 +52,18 @@ try {
|
|||
throw "npm init failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
}
|
||||
|
||||
$src = (Resolve-Path $LocalSourcePath).Path
|
||||
npm.cmd install --save-exact $src tsx@4.21.0 typescript@6.0.3
|
||||
npx.cmd -y @tencent-weixin/openclaw-weixin-cli@latest install
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "npm install local source failed with exit code $LASTEXITCODE"
|
||||
throw "openclaw-weixin-cli install failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
if (-not (Test-Path (Join-Path $sidecarRoot "runner.ts"))) {
|
||||
throw "install completed but runner.ts is missing (invalid sidecar package/source)"
|
||||
npm.cmd install openclaw@latest --save tsx@4.21.0 typescript@6.0.3
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "npm install bridge runtime deps failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
if (-not (Test-Path (Join-Path $sidecarRoot "login.ts"))) {
|
||||
throw "install completed but login.ts is missing (invalid sidecar package/source)"
|
||||
}
|
||||
Write-Host "[ok] installed local weixin sidecar into $sidecarRoot"
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
Ensure-OfficialPluginRuntimeDeps
|
||||
Sync-WeixinBridgeRunners
|
||||
Write-Host "[ok] installed official openclaw-weixin plugin sidecar runtime into $sidecarRoot"
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ try {
|
|||
npm.cmd exec -- tsx login.ts
|
||||
exit 0
|
||||
}
|
||||
throw "login.ts missing. Re-run weixin_install.ps1 -UseOpenclawCli to install sidecar runtime."
|
||||
throw "login.ts missing. Re-run weixin_install.ps1 to install sidecar runtime."
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,15 +18,11 @@ $logDir = Join-Path $sidecarRoot "logs"
|
|||
$pidFile = Join-Path $sidecarRoot "pid.txt"
|
||||
$bridgeSrc = Join-Path $oclawRoot "runtime\\operations\\weixin_bridge"
|
||||
$pluginRoot = Join-Path $env:USERPROFILE ".openclaw\\extensions\\openclaw-weixin"
|
||||
$runnerMode = [string]($env:AIA_WEIXIN_RUNNER_MODE)
|
||||
if (-not $runnerMode) { $runnerMode = "official" }
|
||||
$runnerMode = $runnerMode.Trim().ToLowerInvariant()
|
||||
|
||||
function Get-SidecarProcesses {
|
||||
$escapedSidecarRoot = $sidecarRoot.Replace("\", "\\")
|
||||
$patterns = @(
|
||||
"*$ChannelId*",
|
||||
"*runner.ts*",
|
||||
"*official_runner.ts*",
|
||||
"*$escapedSidecarRoot*"
|
||||
)
|
||||
|
|
@ -82,7 +78,7 @@ $cleaned = Stop-SidecarProcesses
|
|||
Remove-Item -Force $pidFile -ErrorAction SilentlyContinue
|
||||
|
||||
if (Test-Path $bridgeSrc) {
|
||||
foreach ($name in @("runner.ts", "official_runner.ts", "login.ts")) {
|
||||
foreach ($name in @("official_runner.ts", "login.ts")) {
|
||||
$srcPath = Join-Path $bridgeSrc $name
|
||||
if (Test-Path $srcPath) {
|
||||
Copy-Item -Path $srcPath -Destination (Join-Path $sidecarRoot $name) -Force
|
||||
|
|
@ -92,27 +88,18 @@ if (Test-Path $bridgeSrc) {
|
|||
|
||||
$logPath = Join-Path $logDir "weixin_sidecar.log"
|
||||
$errPath = Join-Path $logDir "weixin_sidecar.err.log"
|
||||
if ((Test-Path (Join-Path $sidecarRoot "runner.ts")) -or (Test-Path (Join-Path $sidecarRoot "official_runner.ts"))) {
|
||||
$runnerFile = "official_runner.ts"
|
||||
if ($runnerMode -eq "legacy") {
|
||||
$runnerFile = "runner.ts"
|
||||
}
|
||||
if ($runnerMode -eq "official") {
|
||||
Ensure-OfficialPluginRuntimeDeps
|
||||
}
|
||||
if (-not (Test-Path (Join-Path $sidecarRoot $runnerFile))) {
|
||||
throw "selected runner file missing: $runnerFile"
|
||||
}
|
||||
if (Test-Path (Join-Path $sidecarRoot "official_runner.ts")) {
|
||||
Ensure-OfficialPluginRuntimeDeps
|
||||
$cmd = "cmd.exe"
|
||||
$args = @(
|
||||
"/c",
|
||||
"cd /d $sidecarRoot && set OCLAW_STATE_DIR=$stateDir&& set AIA_GATEWAY_BASE_URL=$GatewayBaseUrl&& set NODE_PATH=$sidecarRoot\node_modules&& npm.cmd exec -- tsx $runnerFile"
|
||||
"cd /d $sidecarRoot && set OCLAW_STATE_DIR=$stateDir&& set AIA_GATEWAY_BASE_URL=$GatewayBaseUrl&& set NODE_PATH=$sidecarRoot\node_modules&& npm.cmd exec -- tsx official_runner.ts"
|
||||
)
|
||||
$p = Start-Process -FilePath $cmd -ArgumentList $args -WorkingDirectory $sidecarRoot -PassThru -WindowStyle Hidden -RedirectStandardOutput $logPath -RedirectStandardError $errPath
|
||||
Set-Content -Path $pidFile -Value $p.Id
|
||||
Write-Host "[ok] started weixin sidecar pid=$($p.Id) mode=$runnerMode cleaned=$cleaned out=$logPath err=$errPath"
|
||||
Write-Host "[ok] started weixin sidecar pid=$($p.Id) mode=official cleaned=$cleaned out=$logPath err=$errPath"
|
||||
exit 0
|
||||
}
|
||||
|
||||
throw "No runner.ts/official_runner.ts found in sidecar root. Re-run weixin_install.ps1 -UseOpenclawCli."
|
||||
throw "official_runner.ts missing in sidecar root. Re-run weixin_install.ps1."
|
||||
|
||||
|
|
|
|||
|
|
@ -10,12 +10,11 @@ def _read(rel: str) -> str:
|
|||
return (REPO_ROOT / rel).read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_weixin_start_defaults_to_official_runner() -> None:
|
||||
def test_weixin_start_official_only_runner() -> None:
|
||||
text = _read("runtime/operations/scripts/weixin_start.ps1")
|
||||
assert '$runnerMode = "official"' in text
|
||||
assert '$runnerFile = "official_runner.ts"' in text
|
||||
assert 'AIA_WEIXIN_RUNNER_MODE' in text
|
||||
assert "mode=official" in text
|
||||
assert 'official_runner.ts' in text
|
||||
assert "AIA_WEIXIN_RUNNER_MODE" not in text
|
||||
|
||||
|
||||
def test_weixin_status_and_stop_track_official_runner() -> None:
|
||||
|
|
@ -27,8 +26,10 @@ def test_weixin_status_and_stop_track_official_runner() -> None:
|
|||
|
||||
def test_weixin_install_copies_official_runner() -> None:
|
||||
text = _read("runtime/operations/scripts/weixin_install.ps1")
|
||||
assert 'Copy-Item -Path (Join-Path $bridgeSrc "official_runner.ts")' in text
|
||||
assert "Sync-WeixinBridgeRunners" in text
|
||||
assert '"official_runner.ts"' in text
|
||||
assert "Ensure-OfficialPluginRuntimeDeps" in text
|
||||
assert "LocalSourcePath" not in text
|
||||
|
||||
|
||||
def test_weixin_start_ensures_plugin_runtime_deps() -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue