feat: validate single-client broadcast operations
Build web service image / build (push) Successful in 1m9s
Build web service image / build (push) Successful in 1m9s
This commit is contained in:
+31
-1
@@ -2,6 +2,8 @@
|
||||
|
||||
状态以 `GET /api/v1/capabilities` 为准;`implemented` 不代表 `validated`,数据库指纹也不代表当前 UI 账号绑定。
|
||||
|
||||
> 多 Client 约束:平台可同时连接多个 Desktop Agent/Client;任务、事件、账号绑定和 UI 业务上下文按 `client_id`(内部可兼容 `node_id`)隔离。单个 Client 掉线只影响其自身任务和事件流,不得让其它 Client 进入离线或停止操作。
|
||||
|
||||
| 操作 | REST | MCP | 当前状态 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 服务/微信诊断 | `GET /api/v1/status`、`/api/v1/diagnostics` | `agent_status`、`agent_diagnose` | Ready/环境依赖 | 脱敏;服务在线不等于微信可用,不执行恢复或 UI 写操作 |
|
||||
@@ -13,10 +15,38 @@
|
||||
| 数据库消息/合并记录 | `GET /api/v1/db/messages`、`/api/v1/db/merged` | `db_messages`、`db_merged` | Implemented but disabled | 仅接受显式已验证账号 fingerprint;只读 SQLCipher,未提供通用 SQL |
|
||||
| 任务查询/取消 | `GET /api/v1/operations`、`/api/v1/operations/{id}`、`POST /api/v1/operations/{id}/cancel` | `operations_list`、`operation_get`、`operation_cancel` | Ready | 按 principal 隔离;`accountId` 仅为调用方视图筛选,不是账号授权;取消不撤销已发生副作用 |
|
||||
| 事件流 | `GET /api/v1/events` | 暂未注册 | Explicit opt-in | SSE 有界缓存、Last-Event-ID gap、Windows `ListenEventsAsync` 已接入;默认关闭,需受控真机验收后开启 |
|
||||
| 单目标文本发送 | `POST /api/v1/operations`,`kind=send-text` | `operation_submit` | Implemented but disabled | 已接入任务/幂等/写后确认契约;`send-text` 保持 disabled,须完成账号绑定、目标唯一性和 Windows 真机验收后才能开放 |
|
||||
| 单目标文本发送 | `POST /api/v1/operations`,`kind=send-text` | `operation_submit` | Implemented(仅验证模式开放) | 已完成单 Client 账号绑定、目标唯一性、确认、幂等和 Windows 真机写后确认;默认部署仍只读,Web UI 直接提交继续门控 |
|
||||
| 多目标文本群发 | `POST /api/v1/operations`,`kind=broadcast-text` | `operation_submit` | Implemented(仅验证模式开放) | 冻结 1–20 个可见且唯一的会话 automation ID,串行逐项发送、记录结果、按错误停止并支持幂等重放;真实单 Client 最终已完成两个白名单目标均成功的群发验收,并保留失败停止证据 |
|
||||
| 文件/卡片发送、联系人/群管理、朋友圈 | — | — | Deferred/Disabled | 遵循 `docs/PENDING.md`,需单项授权和真机证据 |
|
||||
| 任意 SQL/UI 菜单/shell | — | — | Unsupported | 不提供 |
|
||||
|
||||
## 本轮普通用户工作台状态(2026-09-19)
|
||||
|
||||
| 范围 | 当前状态 | 验证边界 |
|
||||
| --- | --- | --- |
|
||||
| 消息首页、会话和消息正文 | 已实现/只读已验证 | 通过真实控制面读取任务和双 Client 联调;仅显示当前 Client 的数据 |
|
||||
| 通讯录/群列表 | 已实现/只读已验证 | 通过真实控制面读取任务联调;添加好友保持禁用 |
|
||||
| 任务中心 | 已实现/只读已验证 | 展示 Client 归属、状态和结果;不提供未经验收的写操作重试 |
|
||||
| 多 Client 选择与隔离 | 已实现/协议及浏览器已验证 | `client_id`/`node_id`、连接代次、任务和事件按 Client 隔离;掉线任务进入等待/待核对,不自动跨 Client 改投 |
|
||||
| 发送、群发、添加好友 | 发送/群发已具备验证模式入口;添加好友禁用 | 单 Client 白名单对象已完成发送与 `broadcast-text` 多目标逐项/停止/幂等验证;默认部署和 Web UI 直接写入口仍安全门控,添加好友不在本轮 |
|
||||
|
||||
详细步骤、自动检查和 Windows 证据见 [WebUI-MCP-2026-09-19 验收记录](validation/WebUI-MCP-2026-09-19.md)。
|
||||
|
||||
## 单 Client 生产验证状态(2026-09-19)
|
||||
|
||||
| 范围 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `.mcp.json` Windows 直连、真实 Session 1、账号绑定 | 已验证 | 使用真实微信 UI 和本地 Client 服务;未使用 Session 0 或 fake Client |
|
||||
| 会话、消息、联系人、群只读 | 已验证 | 真实账号 Rogee;会话/消息/白名单联系人及群查询通过 |
|
||||
| 单消息发送 | 已验证(受控) | 文件传输助手通过 Windows MCP 发送并在 UIA 中确认;服务 send-text 保留确认、幂等和目标校验 |
|
||||
| 普通群消息 | 已验证(受控) | 吉祥三宝通过可见会话 automation ID 发送并返回 `Succeeded`;群预览完成写后确认 |
|
||||
| 多目标文本群发 | 已验证(受控) | 最终真实 `broadcast-text` 冻结“文件传输助手”和“吉祥三宝”两个目标,逐项均返回 `Succeeded`,并确认幂等重放不创建第二次群发;此前失败项按 `stopOnError` 停止的记录也保留。 |
|
||||
| `@所有人` / `group-at-all` | 禁用 | 当前没有注册独立操作,不能宣称已验证 |
|
||||
| 添加好友 | 禁用 | 本轮明确排除,未进行真实联系人变更 |
|
||||
| 多 Client / 跨 Client 故障恢复 | 未纳入 | 本轮只验收单 Client |
|
||||
|
||||
详细操作 ID、失败结果、版本差异和剩余风险见 [单 Client 生产验证记录](validation/WebUI-MCP-single-client-2026-09-19.md)。
|
||||
|
||||
## 运行边界
|
||||
|
||||
- 可通过 `WxAgent.Host serve --config <file>` 启动;安装版使用托盘程序,服务设置和唯一 Token 均在同一个系统设置窗口完成。默认监听 `127.0.0.1`,外部 IP 必须显式 `allowExternal: true`。
|
||||
|
||||
+34
-1
@@ -31,7 +31,7 @@
|
||||
### 1.2 首版范围
|
||||
|
||||
- 本机或外部浏览器、HTTP 客户端与 MCP 客户端访问同一 Host;外部访问必须认证,HTTP 与 MCP 共用 Token、身份及权限。默认仍仅监听回环地址,外部 HTTP 监听须显式启用;不要求 HTTPS。
|
||||
- 一个交互式 Windows 用户会话、一个自动化控制目标;多数据库账号可显式选择,但不承诺多微信实例并行控制。
|
||||
- 支持多个 Client/ Desktop Agent 同时连接控制平台;每个 Client 绑定一个交互式 Windows 用户会话和一个自动化控制目标。多数据库账号可显式选择,但不承诺单个 Client 多微信实例并行控制。
|
||||
- 完成诊断、会话、基础消息、受控文件、只读联系人/群成员、监听及任务中心。
|
||||
- 管理和朋友圈等风险功能按能力状态逐项接入,不默认开放未经真机验收的写操作。
|
||||
- 支持经 Token 认证的外部 HTTP 入口;明文传输不具备保密性,不作为安全公网部署方案。暂不做多租户、Windows Service、自动升级、批量营销或绕过已有确认门禁的破坏性操作。
|
||||
@@ -87,6 +87,39 @@ node-agent/WxAgent.Core/ 必要的跨平台契约、校验和任务状
|
||||
- 监听器只在短快照采集时占用 UI 调度,不持锁等待整个监听生命周期;不同目标冲突时排队或明确拒绝,不偷偷切换。
|
||||
- 关闭服务时停止接单、取消未执行任务、保存已有监听 checkpoint;重启不自动重放写任务。
|
||||
|
||||
### 2.3 多 Client 连接与故障隔离
|
||||
|
||||
本节中的 **Client** 指连接控制平台的 Desktop Agent/微信运行端,对应现有 `node_id`;浏览器、HTTP 和 MCP 是调用方。平台的 Client 注册表、心跳、任务路由和事件流必须按 Client 隔离,不能把 Client 状态做成全局单例。
|
||||
|
||||
#### 设计约束
|
||||
|
||||
- 每个 Client 使用稳定 `client_id`(内部可兼容 `node_id`)和独立连接租约/代次;重连不得把旧连接的迟到心跳写回新连接。
|
||||
- 任务、消息、事件和绑定的作用域至少为 `(client_id, account_id, target_id)`;相同账号或会话名称在不同 Client 上也不得自动合并。
|
||||
- 控制面可以共享任务存储和认证,但每个 Client 必须有独立执行队列。一个 Client 的 UI 自动化占用只影响该 Client,不得阻塞其它 Client 的队列。
|
||||
- Client 掉线只更新该 Client 的状态并停止投递到该 Client;其它 Client 继续接收任务、事件和心跳。只有全部 Client 都不可用时,平台才报告“无可用 Client”。
|
||||
- 目标 Client 掉线时,运行中的只读任务失败并可重新发起;可能已经产生副作用的写任务进入 `Unconfirmed`,禁止自动重试或改投其它 Client。
|
||||
- 尚未执行的写任务进入 `WaitingForClient`/“等待 Client”,Client 重连后不自动重放;用户必须查看目标和内容后显式恢复或新建任务。其它 Client 的任务不受影响。
|
||||
- 每个 Client 的 SSE/订阅独立关闭和恢复;一个订阅断开不得关闭控制面的其它订阅。事件游标必须带 Client 作用域。
|
||||
- UI 的 Client 切换器只切换业务上下文,不清空其它 Client 的任务历史;当前 Client 不可用时显示局部错误和切换入口,而不是全局错误页。
|
||||
|
||||
#### 最小契约变更
|
||||
|
||||
| 位置 | 要求 |
|
||||
| --- | --- |
|
||||
| Client 注册/心跳 | `client_id`、连接代次、最后心跳、微信状态和能力独立记录;迟到连接不能覆盖新连接 |
|
||||
| 任务 | 保留 `node_id` 兼容字段,同时在对外文案使用 Client;任务创建、查询、取消均校验目标 Client |
|
||||
| 事件/SSE | 订阅、游标、缓存和断线恢复按 Client 分区;禁止跨 Client 复用游标 |
|
||||
| 前端状态 | `selectedClientId` 与 `globalAvailability` 分离;单 Client 离线只影响选中上下文 |
|
||||
| 调度 | 共用持久化存储可以保留,但执行队列、门禁、超时和取消状态按 Client 管理 |
|
||||
|
||||
#### 验收用例
|
||||
|
||||
1. 同时连接 Client A、Client B;A 掉线后,B 仍可查看会话、接收事件并提交任务。
|
||||
2. A 的任务进入 `WaitingForClient` 或 `Unconfirmed`,B 的任务继续执行;A 重连不自动重放写任务。
|
||||
3. 在 A/B 之间切换时,会话列表、消息、任务状态和错误不会串用;同名账号/会话仍按 Client 分开。
|
||||
4. A 的事件流断开或游标过期时,B 的事件流不受影响;平台只有在 A、B 都不可用时才显示全局离线。
|
||||
5. Client 连接顺序变化、旧心跳迟到、重复注册和重连都不会覆盖其它 Client 的在线状态。
|
||||
|
||||
## 3. 功能、页面与服务映射
|
||||
|
||||
以下 REST 和 MCP 名称为**拟新增契约**,不是现有接口。U0 输出最终逐项操作清单,包括真实方法签名、输入、输出、风险和证据。
|
||||
|
||||
@@ -1,11 +1,50 @@
|
||||
# Web UI 面向普通用户重构落地指导
|
||||
|
||||
> 状态:待实施指导文档,不代表功能已开放或通过验收。
|
||||
> 状态:实现中;文档描述的写操作仍不代表已开放或通过验收。
|
||||
> 产品定位:普通用户连接 Agent 后,可以查看和回复消息、选择对象群发、添加好友、查看执行结果,无需理解 CLI、MCP、UIA 或数据库。
|
||||
> 本文依据当前工作区源码整理;已有未提交修改,不视为已发布版本。本次仅交付文档,不修改运行代码、不开放写权限、不执行微信写操作。
|
||||
> 本文依据当前工作区源码整理;当前工作树包含 Web UI、Client 隔离和协议实现修改,不视为已发布版本。消息/通讯录/任务只读闭环按任务队列接入;Web UI 的发送、群发和加好友提交仍保持安全禁用,后端 `send-text`/`broadcast-text` 仅在明确授权的验证模式下开放。
|
||||
>
|
||||
> 待实施决策:认证成功的 Token 可获取 Agent 当前登录账号的数据,不按 `AccountIds` 做账号级授权隔离;调用方负责账号、页面和业务视图隔离。Agent 仍保留能力权限、账号与窗口绑定一致性、目标核验,并补齐 CSRF/Origin 等服务端安全校验。好友申请冷却明确按“发送账号+目标”计算,为 4 小时。这些是目标行为,不代表当前源码已实现。
|
||||
|
||||
## 0. 已确认的产品与交互基线
|
||||
|
||||
### 0.1 产品模式
|
||||
|
||||
本次改造采用 **Operate(工作台)** 模式,不再把后端接口、节点心跳和诊断指标作为普通用户首页。普通用户默认进入“消息”,目标是完成“确认可用 → 找到会话 → 阅读 → 回复”,而不是理解 Agent、MCP、UIA 或任务队列。
|
||||
|
||||
主导航固定为:
|
||||
|
||||
```text
|
||||
消息(默认)
|
||||
群发
|
||||
通讯录
|
||||
任务
|
||||
设置 → 连接与账号 / 高级诊断
|
||||
```
|
||||
|
||||
群发采用“选择对象 → 编辑内容 → 预览确认 → 执行结果”四步流程;添加好友采用“搜索 → 确认候选 → 填写验证信息 → 提交 → 查看结果”流程。技术字段仅在高级诊断中展示。
|
||||
|
||||
### 0.2 Client 定义
|
||||
|
||||
本文中的 **Client** 指连接控制平台的 Desktop Agent/微信运行端,对应现有控制面中的 `node_id`;浏览器、HTTP 和 MCP 属于调用方,不与 Client 混用。每个 Client 可以绑定自己的微信账号/窗口,但单个 Client 仍只承诺一个交互式 Windows 会话和一个自动化控制目标。
|
||||
|
||||
### 0.3 多 Client 隔离是硬约束
|
||||
|
||||
平台必须支持多个 Client 同时在线,且一个 Client 掉线不能影响其它 Client:
|
||||
|
||||
- Client 使用稳定的 `client_id`(内部可兼容现有 `node_id`)和独立心跳/租约;不得用全局单例表示在线状态。
|
||||
- 连接、账号/窗口绑定、消息会话、事件流、任务路由和执行队列均以 Client 为作用域;业务上下文至少包含 `(client_id, account_id, target_id)`。
|
||||
- UI 顶部提供 Client 选择器。消息、通讯录和写操作必须先选定 Client;“全部 Client”只用于查看健康状态或任务汇总,不能把不同 Client 的同名会话合并。
|
||||
- 顶部显示当前 Client 的状态。当前 Client 掉线时只禁用当前上下文并提供切换入口;只有所有 Client 都不可用时才显示全局不可用。
|
||||
- 运行中的只读任务可失败并允许重新发起;运行中的写任务若无法证明未产生副作用,必须标记“结果待核对”,禁止自动重试或改投其它 Client。
|
||||
- 已排队但尚未执行的写任务在 Client 掉线后进入“等待 Client/需重新确认”,Client 重连不自动重放;其它 Client 的任务继续排队或执行。
|
||||
- 一个 Client 的 SSE/事件断开只关闭该 Client 的订阅,不关闭平台或其它 Client 的事件流。
|
||||
- 任务、事件、错误和审计记录都显示所属 Client,避免用户把乙 Client 的状态误认为甲 Client 的结果。
|
||||
|
||||
### 0.4 本次交付边界
|
||||
|
||||
本轮按本文件落地 Client 选择与隔离、普通用户工作台壳层以及消息/通讯录/任务的只读任务队列接入。Web UI 的发送、群发和添加好友只保留清晰的禁用状态;后端发送/群发能力仅在明确授权的验证模式下使用,默认部署仍需保持只读。
|
||||
|
||||
## 1. 改造结论与范围
|
||||
|
||||
当前 UI 是开发者诊断控制台,目标 UI 应是微信业务工作台。改造不是换配色、加卡片,而是把页面组织方式从“后端有什么接口”改成“用户要完成什么事情”。
|
||||
@@ -22,7 +61,7 @@
|
||||
|
||||
### 1.2 本轮不做
|
||||
|
||||
- 不引入 CRM、团队客服分配、自动回复机器人、营销自动化、定时发送、多租户、云端中转或多 Agent 并行控制。
|
||||
- 不引入 CRM、团队客服分配、自动回复机器人、营销自动化、定时发送、多租户或云端中转;支持多个 Client 同时连接控制平台,但不承诺单个 Client 多微信实例并行控制。
|
||||
- 不承诺读取全部会话、全部历史或离线消息必达;不实现“下一个未读会话”。
|
||||
- 不顺带开放朋友圈、删除好友、移出群成员等高风险操作。
|
||||
- 不引入新前端框架、通用工作流引擎、独立消息队列或 Windows Service。
|
||||
@@ -48,7 +87,7 @@
|
||||
| 消息 | 列出可见会话和当前可见消息;当前前端没有完整会话点击/回复流程 | 会话导航、正文权限引导、聊天布局、发送接口和结果验证 |
|
||||
| 联系人/群 | 已有数据库只读分页查询接口;前端加载首批联系人 | 搜索、加载更多、选中名单和稳定目标解析 |
|
||||
| 导航/历史 | 已有部分路由;导航待验收、数据库消息能力存在禁用项 | 不得把“接口存在”当成“页面可直接使用” |
|
||||
| 单条发送 | 服务层尚无文本发送入口,功能矩阵标记 Disabled | 接入现有 Windows 业务方法、权限/唯一目标/写后确认、真机验收 |
|
||||
| 单条发送 | 服务层已有 `send-text` 验证模式入口;Web UI 直接提交仍门控 | 继续保留账号/权限/唯一目标/写后确认,并以单 Client 真机记录作为受控证据 |
|
||||
| 群发/加好友 | 尚无 Web 业务闭环 | 有界批量任务、单人好友申请接口及端到端验收 |
|
||||
| 任务 | 持久化队列、按 ID 查询/取消、幂等与重启状态处理 | 缺少任务列表、业务结果字段、批量逐项结果;不是只改前端就能补齐 |
|
||||
| 事件 | 服务端已有 SSE,默认关闭,需显式启用并验收;当前前端主要手动或每 15 秒刷新 | 前端事件接入、断线恢复与缺口提示,不能宣称完整实时收件箱 |
|
||||
@@ -240,8 +279,8 @@ Agent 自己的 `operations.sqlite` 可以保存业务任务元数据;这不
|
||||
| 建议入口 | 用途 | 必须校验/返回 |
|
||||
| --- | --- | --- |
|
||||
| `GET /api/v1/operations` | 当前身份的任务列表 | 按当前登录 principal 过滤;可按 `accountId` 筛选但不做 Token 账号授权拒绝;有界分页、摘要,不泄漏其他 principal 的任务 |
|
||||
| `POST /api/v1/operations`,`kind=send-text` | 单目标文本发送 | **基础已接入但 capability disabled**;accountId、AutomationId 目标引用、text、idempotencyKey、confirmed;受理返回任务 ID,不直接宣称成功;开放前须完成 Windows 真机验收 |
|
||||
| 同入口,`kind=broadcast-text` | 提交有界群发 | 冻结目标列表、去重、条数/长度限制、显式确认、逐项幂等与批次详情 |
|
||||
| `POST /api/v1/operations`,`kind=send-text` | 单目标文本发送 | **验证模式入口已接入,默认部署和 Web UI 仍门控**;accountId、AutomationId 目标引用、text、idempotencyKey、confirmed;受理返回任务 ID,只有写后确认才标成功;单 Client 真机证据见验收记录 |
|
||||
| 同入口,`kind=broadcast-text` | 提交有界群发 | **验证模式入口已接入,默认部署和 Web UI 仍门控**;冻结目标列表、去重、条数/长度限制、显式确认、串行逐项结果、停止和幂等详情 |
|
||||
| `POST /api/v1/friend-search` | 好友候选预览 | Token/能力、绑定状态、超时、候选归属当前账号;不发送申请 |
|
||||
| `POST /api/v1/operations`,`kind=friend-request` | 单人好友申请 | 当前账号绑定的有效候选引用、验证信息、显式确认、幂等键;按 §4.4 原子接纳并执行,发送账号+目标稳定身份冷却 4 小时,返回任务或冷却 `retryAt` |
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# Web UI / MCP 验收记录(2026-09-19)
|
||||
|
||||
## 范围
|
||||
|
||||
本记录验证普通用户 Web 工作台、多 Client 隔离,以及消息、通讯录、任务的只读任务队列闭环;它是只读基线,不覆盖随后单 Client 验证模式下的写操作。Web UI 的发送、群发、添加好友提交仍保持禁用;真实 Client API 的 `send-text`/`broadcast-text` 受控证据见[单 Client 生产验证记录](WebUI-MCP-single-client-2026-09-19.md)。
|
||||
|
||||
## Linux 自动检查
|
||||
|
||||
| 检查 | 结果 |
|
||||
| --- | --- |
|
||||
| `cd control-plane && go test ./...` | 通过 |
|
||||
| `cd control-plane/web && npm run build` | 通过;生成 `index-BkrtfWai.css`、`index-_unPe9bQ.js` |
|
||||
| `dotnet test tests/node-agent/WxAgent.Core.Tests -c Release --no-restore` | 通过;168 tests,0 failed,0 skipped |
|
||||
| `dotnet build WxAgent.sln -c Release -p:EnableWindowsTargeting=true --no-restore` | 通过;0 warnings,0 errors |
|
||||
| `git diff --check` | 通过 |
|
||||
|
||||
## Web UI 只读联调
|
||||
|
||||
- 控制面:`http://127.0.0.1:8090/`;测试身份为本地测试管理员。
|
||||
- 使用两个隔离的 fake Client(`client-a` / `client-b`)持续发送 heartbeat,并只处理真实控制面任务队列中的读取任务;fake Client 不是产品能力,也不计入 Windows 真机通过数。
|
||||
- 浏览器实测消息页默认打开;Client 切换后会清空旧会话上下文并丢弃过期响应。
|
||||
- Client A 的会话、消息正文、通讯录/群和任务记录均可通过队列读取;切换 Client 后不串用数据。
|
||||
- 发送按钮、群发提交、添加好友按钮均保持 `disabled`,并显示未完成能力/真机验收原因。
|
||||
- 桌面及 390px 窄屏布局通过浏览器检查,无横向溢出;加载、空列表、离线、错误和权限提示由 UI 提供明确状态。
|
||||
|
||||
## Windows 真机检查
|
||||
|
||||
发布包为 `WxAgent.Host` self-contained `win-x64` single-file,上传至 `C:\Users\Rogee\wx-agent`,在已登录的交互式 Windows 用户会话(Session 1)中执行:
|
||||
|
||||
- 微信版本:`4.1.13.65`。
|
||||
- `doctor`:通过;`WindowFound=true`,`MainView/session_list/chat_message_page/chat_message_list/chat_input_field/tool_bar_accessible` 均为 `true`,`Errors=[]`,`InputDesktopAvailable=true`。
|
||||
- `inspect-ui --output artifacts/ui-tree.json`:通过;164 个脱敏节点,`sanitized=true`。
|
||||
- `smoke`:通过;`scope=M1`,目标为白名单“文件传输助手”,`sendSkipped=false`,`confirmed=true`。该命令是既有 CLI smoke 的受控写验证,不代表 Web UI 已开放写操作。
|
||||
|
||||
## 未完成/保留限制
|
||||
|
||||
- Web UI 的消息发送、群发、添加好友提交继续禁用;后端验证模式的 `send-text` 与 `broadcast-text` 已有真实单 Client 证据,详见单 Client 记录,默认部署仍保持只读。
|
||||
- fake Client 只验证控制面任务路由和 Client 隔离,不替代真实 Desktop Agent 的只读能力验收。
|
||||
- 未进行外部网络部署、MCP 客户端兼容性和长时事件流验收;不改变功能矩阵中对应状态。
|
||||
@@ -0,0 +1,69 @@
|
||||
# Web UI / MCP 单 Client 生产验证记录(2026-09-19)
|
||||
|
||||
## 验证范围
|
||||
|
||||
通过项目 `.mcp.json` 连接 Windows MCP,在已登录、未锁定的 Session 1 中验证一个真实微信 Client(账号 Rogee)。本轮不验证添加好友和多 Client;只使用白名单对象:文件传输助手、Hao 豪、吉祥三宝、消息测试专用群组。
|
||||
|
||||
## 连接与放行
|
||||
|
||||
- `.mcp.json` 的 `windows-ui` endpoint:`http://10.1.1.101:8765/mcp`;连接成功。
|
||||
- Windows `WxAgent.Tray` 在 Session 1 运行;微信版本由 status 报告为 `4.1.13.65`。
|
||||
- `GET /api/v1/status` 返回 200:service、WeChat、session、window 和 active account binding 均可用,未使用 Session 0。
|
||||
- UI target `11460:81724928` 与账号 Rogee 绑定,`isBound=true`。
|
||||
- 本轮在单 Client 的 `service.json` 显式启用 `enableValidationOperations=true`;`local-admin` 凭据获得 `write` 权限。代码默认仍为关闭,普通部署不自动放行写操作。
|
||||
- capability 当前启用 `session-open`、`sessions-scroll`、`send-text`、`broadcast-text`;两种写能力仅因本机明确授权的 `enableValidationOperations=true` 而开放,普通部署仍保持只读。`group-at-all` 保持 disabled,因为当前 Client 没有注册该独立操作。群消息和受控群发均使用已确认的会话 automation ID。
|
||||
|
||||
## 只读结果
|
||||
|
||||
- UIA 真实会话列表导出 16 个条目,包含“文件传输助手”“Hao 豪”“吉祥三宝”等。
|
||||
- 当前会话读取成功为“文件传输助手”。消息 API 返回 200,4 条真实消息,类型为 Text/Merge/File/Text;使用 `includeContent=false` 验证脱敏读取。
|
||||
- 联系人读取分别命中“文件传输助手”“Hao 豪”“吉祥三宝”;群查询命中“消息测试专用群组”(群 ID 不写入本记录)。
|
||||
- 名称不唯一/不存在时 API 返回 409 NotFound,`retry=false`;没有自动猜测、跨目标改投或自动重试。
|
||||
|
||||
## 写操作结果
|
||||
|
||||
### 文件传输助手
|
||||
|
||||
- 首次通过服务操作提交的错误 target 格式(联系人 ID `filehelper`)得到 `Unconfirmed / ExecutionFailed`,`hasSideEffects=true`;未重放、未自动重试。
|
||||
- 随后使用 Windows MCP 在真实微信输入框发送唯一测试标记 `[WxAgent验证] UI 单 Client 发送验证 20260919-0239`;UIA 消息列表出现该消息,写后确认通过。
|
||||
|
||||
### 吉祥三宝群
|
||||
|
||||
- 使用可见会话 automation ID `session_item_吉祥三宝` 提交 confirmed `send-text`,操作 ID:`c3be6c1e07c14c2f9fdc685357c44993`。
|
||||
- 结果:`state=Succeeded`、`stage=complete`、`hasSideEffects=true`。
|
||||
- 相同 idempotency key 重放返回同一 operation ID,没有创建重复操作;验证了幂等防重。
|
||||
- 微信真实会话列表的“吉祥三宝”预览出现唯一测试标记 `[WxAgent验证] 单 Client 群消息验证 吉祥三宝 20260919-0258`,作为写后 UI 确认。
|
||||
- `confirmed=false` 的负向请求返回 HTTP 409 `ConfirmationRequired`、`retry=false`,没有执行。
|
||||
|
||||
### 多目标文本群发(broadcast-text)
|
||||
|
||||
- 原始 HTTP 响应、请求 fixture、能力/授权状态、幂等重放、确认门禁、只读 sessions/messages 响应和 MCP UIA 摘录已保存于 [`evidence/WebUI-MCP-single-client-2026-09-19/`](evidence/WebUI-MCP-single-client-2026-09-19/),其中 `README.md`、`manifest.json` 和 `sha256sums.txt` 说明采集边界、脱敏规则和校验方式。
|
||||
- 使用真实 Client API 提交 `kind=broadcast-text`,请求携带两个当前可见且唯一的会话 automation ID:`session_item_文件传输助手`、`session_item_吉祥三宝`,并设置 `confirmed=true`、`stopOnError=true`。服务在执行前冻结该名单,不使用联系人 ID 猜测或跨目标改投。
|
||||
- 首次诊断操作 `7b3a9ff33550489eb7fe50478bbd1155` 曾在文件传输助手成功后因吉祥三宝 `ControlNotFound` 按 `stopOnError` 停止;该记录保留为失败停止和幂等证据,未自动重试。
|
||||
- 修正 UI 会话切换为可见中心点击,并将等待聊天页从 2.5 秒扩大到 10 秒后,重新部署最新 self-contained Tray。最终验收操作 ID:`463b37b2e0944525af4ded822dddaf8c`;Correlation ID:`33d6e14673834c64b5d470a07687c760`;`state=Succeeded`、`stage=complete`、`errorCode=null`。
|
||||
- 最终操作冻结同一两个白名单目标:文件传输助手 `Succeeded`、吉祥三宝 `Succeeded`;`stopped=false`、`stopReason=null`。这证明了真实多对象名单冻结、串行逐项发送、两个目标写后确认和成功群发。
|
||||
- 相同 `idempotencyKey=wxagent-single-20260919-broadcast-final-001` 重放返回同一个操作 ID和相同 `Succeeded` 结果(重放请求 Correlation ID:`858fd45fc16e4b1383909d4d406ae8bc`),没有创建第二次群发。服务 capability 实际返回 `send-text`/`broadcast-text` 为 `implemented=true`、`validated=true`、`enabled=true`、`requiresConfirmation=true`,微信版本 `4.1.13.65`;`group-at-all` 仍为 disabled。
|
||||
- 群发结束后分别用只读 `GET /api/v1/messages` 查询两个 automation ID 对应会话,均返回 4 条可见消息,并在不记录完整正文的前提下确认本次唯一标记存在(`markerConfirmed=true`)。
|
||||
|
||||
### 未通过/保持禁用
|
||||
|
||||
- `消息测试专用群组` 当前搜索结果存在多个同名项,使用联系人群 ID 的操作返回 `Unconfirmed / NotFound`;未猜测目标、未重试,仍保持该路径禁用。
|
||||
- `group-at-all` 独立能力没有注册操作,仍禁用;本轮不宣称已验证 @所有人。
|
||||
- 添加好友未验证,入口继续禁用。
|
||||
- 多 Client、跨 Client 故障恢复和远程控制面任务流不属于本轮证据。
|
||||
|
||||
## 自动检查
|
||||
|
||||
- `cd control-plane && go test ./...`:通过。
|
||||
- `cd control-plane/web && npm run build`:通过。
|
||||
- `dotnet test tests/node-agent/WxAgent.Core.Tests -c Release --no-restore`:168 tests 通过。
|
||||
- `dotnet test tests/node-agent/WxAgent.Service.Tests -c Release --no-restore`:22 tests 通过,包含 `broadcast-text` 冻结、顺序、停止和幂等覆盖。
|
||||
- `dotnet build WxAgent.sln -c Release -p:EnableWindowsTargeting=true --no-restore`:0 warnings、0 errors。
|
||||
- `git diff --check`、Go `gofmt`:通过。
|
||||
|
||||
## 风险与后续
|
||||
|
||||
- 版本证据不一致已在最终部署中修正:`GET /api/v1/capabilities` 与 status 均报告微信 `4.1.13.65`,send/broadcast 均为 `validated=true`。
|
||||
- 首次诊断中的错误 target 保留为失败停止证据;没有重试该不确定操作,修复后使用新的显式幂等键完成最终成功验收。
|
||||
- 早期诊断曾出现 60 秒 sessions 队列超时;修复后连续 3 次 sessions 刷新均 HTTP 200、约 2.1–2.3 秒,且两个目标的只读 marker 回读均成功,不再作为本轮验收阻塞项。
|
||||
- 当前验证模式只应留在这台明确授权的单 Client;未授权部署必须保持默认只读。
|
||||
@@ -0,0 +1,40 @@
|
||||
# 单 Client 真实验证原始证据
|
||||
|
||||
本目录保存 2026-09-19 在已登录、未锁定的 Windows Session 1 上采集的原始 HTTP API 响应、请求 fixture、MCP UIA 证据摘录和校验清单。它补充 `../WebUI-MCP-single-client-2026-09-19.md`,不是用文档自述替代接口响应。
|
||||
|
||||
## 采集边界
|
||||
|
||||
- Windows UI MCP:`.mcp.json` 中的 `windows-ui`,`http://10.1.1.101:8765/mcp`。
|
||||
- UI MCP 用于确认真实微信窗口、`MainView`、`session_list`、两个白名单 automation ID、`chat_message_list` 和验收标记;对应的可审计摘录见 `mcp-ui-evidence.json`。
|
||||
- Agent HTTP API 在 Windows 测试服务的本地转发端口访问:`http://127.0.0.1:15088`,请求 Host 为 `localhost:5088`。这不是把 `/api/v1/*` 当作 MCP endpoint,而是记录 `.mcp.json` 连接的真实 Client 所运行服务的认证 API 响应。
|
||||
- 每个 `*.http.txt` 是原始响应头,每个 `*.response.json` 是原始响应体;文件中没有 Bearer token。测试 token 只从本地/远端验证配置读取,未复制到仓库。
|
||||
- 消息只读证据使用 `includeContent=false`,保留条数、fingerprint 和 summary 中的唯一测试标记,不保存完整聊天正文。
|
||||
|
||||
## 证据对应关系
|
||||
|
||||
| 文件 | 证明内容 |
|
||||
| --- | --- |
|
||||
| `status.*` | 服务在线、微信可用、Session 未锁定、账号绑定、微信版本 `4.1.13.65`、默认只读 |
|
||||
| `capabilities.*` | `send-text`/`broadcast-text` 为 implemented、validated、enabled;群发要求确认;`group-at-all` disabled |
|
||||
| `sessions-1..3.*` | 连续 3 次只读会话枚举均 HTTP 200,均含 `session_item_文件传输助手` 和 `session_item_吉祥三宝` |
|
||||
| `broadcast.request.json` | 最终真实群发请求:两个 automation ID、显式确认、幂等键、`stopOnError=true` |
|
||||
| `broadcast-submit.*` | 原始 POST 受理响应:HTTP 200、operation `463b37b2e0944525af4ded822dddaf8c`、`Queued`、冻结目标详情 |
|
||||
| `broadcast-get.*` | 原始最终操作响应:operation `463b37b2e0944525af4ded822dddaf8c`、`Succeeded/complete`、两个逐项 `Succeeded` |
|
||||
| `broadcast-replay.*` | 相同幂等请求的原始重放响应,返回相同 operation ID 和结果 |
|
||||
| `confirmation-gate.*` | `confirmed=false` 的真实 `broadcast-text` 请求返回 HTTP 409 `ConfirmationRequired`,`retry=false` |
|
||||
| `send-confirmation-gate.*` | `confirmed=false` 的真实 `send-text` 请求返回 HTTP 409 `ConfirmationRequired`,`retry=false` |
|
||||
| `messages-filehelper.*`, `messages-jixiang.*` | 两个目标的原始只读消息响应;summary 含本次唯一标记、content 为 null |
|
||||
| `readback-summary.json` | 从上述 raw 只读响应计算的脱敏回读结论 |
|
||||
| `mcp-ui-evidence.json` | UI MCP 实时窗口/UIA 树中真实微信、白名单会话、消息列表和标记的证据摘录 |
|
||||
|
||||
## 关键断言
|
||||
|
||||
- 最终 operation:`463b37b2e0944525af4ded822dddaf8c`,Correlation ID:`33d6e14673834c64b5d470a07687c760`。
|
||||
- 最终详情的冻结顺序为文件传输助手、吉祥三宝;两项均 `Succeeded`,`stopped=false`,无错误码。
|
||||
- 相同幂等键 `wxagent-single-20260919-broadcast-final-001` 的重放仍返回该 operation ID,不创建第二次操作。
|
||||
- 失败停止流程的早期原始记录仍在主验收文档中,避免只保留成功路径;最终验收使用了新的显式幂等键。
|
||||
- `group-at-all`、添加好友、多 Client/跨 Client 恢复不属于本轮证据。
|
||||
|
||||
## 复核方式
|
||||
|
||||
在已授权的验证机上设置临时 shell 变量 `TOKEN` 后,可按 `*.http.txt` 中的 Host 和路径重放 GET;不得把 token 写入文件或日志。POST 请求只能使用目录中的 confirmation-gate fixture(应返回 409)或最终 broadcast fixture(相同幂等键应返回相同操作),不得绕过确认门禁或使用真实非白名单对象。
|
||||
@@ -0,0 +1,10 @@
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Date: Sat, 19 Sep 2026 04:22:44 GMT
|
||||
Server: Kestrel
|
||||
Cache-Control: no-store
|
||||
Transfer-Encoding: chunked
|
||||
X-Correlation-Id: 35ec468485244ba98ba9751327d6b5f7
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"id":"463b37b2e0944525af4ded822dddaf8c","principalId":"local-admin","accountId":"a2e8a1eaab7fd5fbd3806525c0d9cce750c28f4efb8e7cfcabc9e3e8660e0277","capability":"broadcast-text","state":"Succeeded","stage":"complete","correlationId":"33d6e14673834c64b5d470a07687c760","createdAt":"2026-09-19T04:09:45.5025818+00:00","expiresAt":"2026-09-19T04:14:45.5025818+00:00","errorCode":null,"hasSideEffects":true,"details":"{\"targetIds\":[\"session_item_\\u6587\\u4EF6\\u4F20\\u8F93\\u52A9\\u624B\",\"session_item_\\u5409\\u7965\\u4E09\\u5B9D\"],\"items\":[{\"targetId\":\"session_item_\\u6587\\u4EF6\\u4F20\\u8F93\\u52A9\\u624B\",\"state\":\"Succeeded\",\"errorCode\":null},{\"targetId\":\"session_item_\\u5409\\u7965\\u4E09\\u5B9D\",\"state\":\"Succeeded\",\"errorCode\":null}],\"stopped\":false,\"stopReason\":null}"}
|
||||
@@ -0,0 +1,10 @@
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Date: Sat, 19 Sep 2026 04:22:44 GMT
|
||||
Server: Kestrel
|
||||
Cache-Control: no-store
|
||||
Transfer-Encoding: chunked
|
||||
X-Correlation-Id: 94d46404d54a43babfe5bb855f767518
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"id":"463b37b2e0944525af4ded822dddaf8c","principalId":"local-admin","accountId":"a2e8a1eaab7fd5fbd3806525c0d9cce750c28f4efb8e7cfcabc9e3e8660e0277","capability":"broadcast-text","state":"Succeeded","stage":"complete","correlationId":"33d6e14673834c64b5d470a07687c760","createdAt":"2026-09-19T04:09:45.5025818+00:00","expiresAt":"2026-09-19T04:14:45.5025818+00:00","errorCode":null,"hasSideEffects":true,"details":"{\"targetIds\":[\"session_item_\\u6587\\u4EF6\\u4F20\\u8F93\\u52A9\\u624B\",\"session_item_\\u5409\\u7965\\u4E09\\u5B9D\"],\"items\":[{\"targetId\":\"session_item_\\u6587\\u4EF6\\u4F20\\u8F93\\u52A9\\u624B\",\"state\":\"Succeeded\",\"errorCode\":null},{\"targetId\":\"session_item_\\u5409\\u7965\\u4E09\\u5B9D\",\"state\":\"Succeeded\",\"errorCode\":null}],\"stopped\":false,\"stopReason\":null}"}
|
||||
@@ -0,0 +1,10 @@
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Date: Sat, 19 Sep 2026 04:09:45 GMT
|
||||
Server: Kestrel
|
||||
Cache-Control: no-store
|
||||
Transfer-Encoding: chunked
|
||||
X-Correlation-Id: 57fc0ed311354f1586bcfd308dd54c7e
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"id":"463b37b2e0944525af4ded822dddaf8c","principalId":"local-admin","accountId":"a2e8a1eaab7fd5fbd3806525c0d9cce750c28f4efb8e7cfcabc9e3e8660e0277","capability":"broadcast-text","state":"Queued","stage":"queued","correlationId":"33d6e14673834c64b5d470a07687c760","createdAt":"2026-09-19T04:09:45.5025818+00:00","expiresAt":"2026-09-19T04:14:45.5025818+00:00","errorCode":null,"hasSideEffects":true,"details":"{\"targetIds\":[\"session_item_\\u6587\\u4EF6\\u4F20\\u8F93\\u52A9\\u624B\",\"session_item_\\u5409\\u7965\\u4E09\\u5B9D\"],\"stopOnError\":true}"}
|
||||
@@ -0,0 +1 @@
|
||||
{"kind":"broadcast-text","accountId":"a2e8a1eaab7fd5fbd3806525c0d9cce750c28f4efb8e7cfcabc9e3e8660e0277","targets":["session_item_文件传输助手","session_item_吉祥三宝"],"text":"[WxAgent验证] 单 Client 多对象广播修复验收 20260919-0412","idempotencyKey":"wxagent-single-20260919-broadcast-final-001","confirmed":true,"stopOnError":true}
|
||||
@@ -0,0 +1,10 @@
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Date: Sat, 19 Sep 2026 04:22:44 GMT
|
||||
Server: Kestrel
|
||||
Cache-Control: no-store
|
||||
Transfer-Encoding: chunked
|
||||
X-Correlation-Id: 65c675b23d324a6ea793c356da41fb51
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'
|
||||
File diff suppressed because one or more lines are too long
+10
@@ -0,0 +1,10 @@
|
||||
HTTP/1.1 409 Conflict
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Date: Sat, 19 Sep 2026 04:15:34 GMT
|
||||
Server: Kestrel
|
||||
Cache-Control: no-store
|
||||
Transfer-Encoding: chunked
|
||||
X-Correlation-Id: 3183a2753a044909b14f73336dcbe170
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"kind":"broadcast-text","accountId":"a2e8a1eaab7fd5fbd3806525c0d9cce750c28f4efb8e7cfcabc9e3e8660e0277","targets":["session_item_文件传输助手","session_item_吉祥三宝"],"text":"[WxAgent验证] confirmation gate must not send 20260919-0414","idempotencyKey":"wxagent-single-20260919-confirmation-gate-001","confirmed":false,"stopOnError":true}
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"correlationId":"3183a2753a044909b14f73336dcbe170","error":{"code":"ConfirmationRequired","message":"Explicit send confirmation is required.","stage":"request","retry":false}}
|
||||
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"collectedAtUtc": "2026-09-19T04:15:34Z",
|
||||
"purpose": "Auditable raw evidence for the final single-Client Windows WeChat validation.",
|
||||
"mcp": {
|
||||
"config": ".mcp.json",
|
||||
"server": "windows-ui",
|
||||
"endpoint": "http://10.1.1.101:8765/mcp",
|
||||
"uiEvidence": "mcp-ui-evidence.json"
|
||||
},
|
||||
"serviceApi": {
|
||||
"baseUrl": "http://127.0.0.1:15088",
|
||||
"hostHeader": "localhost:5088",
|
||||
"authentication": "Bearer token used only by the local validation shell; no token is stored in this directory."
|
||||
},
|
||||
"boundAccountId": "a2e8a1eaab7fd5fbd3806525c0d9cce750c28f4efb8e7cfcabc9e3e8660e0277",
|
||||
"wechatVersion": "4.1.13.65",
|
||||
"finalOperation": {
|
||||
"id": "463b37b2e0944525af4ded822dddaf8c",
|
||||
"submitCorrelationId": "57fc0ed311354f1586bcfd308dd54c7e",
|
||||
"correlationId": "33d6e14673834c64b5d470a07687c760",
|
||||
"submitResponse": "broadcast-submit.response.json",
|
||||
"capability": "broadcast-text",
|
||||
"targets": ["session_item_文件传输助手", "session_item_吉祥三宝"],
|
||||
"state": "Succeeded",
|
||||
"stage": "complete",
|
||||
"itemStates": ["Succeeded", "Succeeded"],
|
||||
"stopped": false,
|
||||
"replayResponse": "broadcast-replay.response.json"
|
||||
},
|
||||
"confirmationGates": {
|
||||
"broadcastText": {
|
||||
"request": "confirmation-gate.request.json",
|
||||
"httpStatus": 409,
|
||||
"errorCode": "ConfirmationRequired",
|
||||
"retry": false,
|
||||
"correlationId": "3183a2753a044909b14f73336dcbe170"
|
||||
},
|
||||
"sendText": {
|
||||
"request": "send-confirmation-gate.request.json",
|
||||
"httpStatus": 409,
|
||||
"errorCode": "ConfirmationRequired",
|
||||
"retry": false,
|
||||
"correlationId": "78820fff9db246feb032a873018d43bb"
|
||||
}
|
||||
},
|
||||
"readOnlyEvidence": {
|
||||
"status": "status.response.json",
|
||||
"capabilities": "capabilities.response.json",
|
||||
"sessions": ["sessions-1.response.json", "sessions-2.response.json", "sessions-3.response.json"],
|
||||
"messages": ["messages-filehelper.response.json", "messages-jixiang.response.json"]
|
||||
},
|
||||
"integrity": {
|
||||
"algorithm": "SHA-256",
|
||||
"fileList": "sha256sums.txt",
|
||||
"scope": "All evidence files except manifest.json and sha256sums.txt; README and derived summaries are included."
|
||||
},
|
||||
"redactions": [
|
||||
"Authorization headers/tokens are not stored.",
|
||||
"Message API evidence uses includeContent=false; full chat bodies are not stored.",
|
||||
"The bound account ID and test marker are retained because they are required to correlate the operation and read-back evidence."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"source": {
|
||||
"mcpConfig": ".mcp.json",
|
||||
"server": "windows-ui",
|
||||
"endpoint": "http://10.1.1.101:8765/mcp",
|
||||
"listTool": "windows-ui_list_windows",
|
||||
"inspectTool": "windows-ui_inspect_window",
|
||||
"inspectArgs": {"title_re": "^微信$", "found_index": 0},
|
||||
"note": "This is a redacted, auditable excerpt of the live MCP UIA response; rectangles and automation IDs are copied from the tool result. Message bodies are not stored here."
|
||||
},
|
||||
"visibleTopLevelWindows": ["任务栏", "微信", "操作提示", "设置标题", "JP-Word->033.jpwabc ==> C:\\temp\\jpw7-batch\\, (cpu=0.0)", "微信", "新标签页 - 夸克", "10.1.1.104 - Google Chrome", "QQ", "dummyLayeredWnd", "dummyLayeredWnd", "Program Manager"],
|
||||
"requiredNodes": [
|
||||
{"name": "微信", "type": "Window", "automationId": "", "rectangle": "(L371, T56, R1204, B729)"},
|
||||
{"name": "", "type": "Group", "automationId": "MainView", "rectangle": "(L371, T57, R1204, B729)"},
|
||||
{"name": "会话", "type": "List", "automationId": "session_list", "rectangle": "(L431, T137, R671, B677)"},
|
||||
{"name": "文件传输助手\\n已置顶\\nNative Writer\\n12:17\\n", "type": "ListItem", "automationId": "session_item_文件传输助手", "rectangle": "(L431, T137, R671, B202)"},
|
||||
{"name": "吉祥三宝\\n已置顶\\n[WxAgent验证] 单 Client 多对象广播修复验收 20260919-0412\\n12:09\\n", "type": "ListItem", "automationId": "session_item_吉祥三宝", "rectangle": "(L431, T202, R671, B267)"},
|
||||
{"name": "", "type": "Group", "automationId": "chat_message_page", "rectangle": "(L671, T89, R1200, B725)"},
|
||||
{"name": "文件传输助手", "type": "Text", "automationId": "content_view.top_content_view.title_h_view.left_v_view.left_content_v_view.left_ui_.big_title_line_h_view.current_chat_name_label", "rectangle": "(L687, T102, R771, B122)"},
|
||||
{"name": "消息", "type": "List", "automationId": "chat_message_list", "rectangle": "(L671, T137, R1200, B585)"},
|
||||
{"name": "[WxAgent验证] 单 Client 多对象广播修复验收 20260919-0412", "type": "ListItem", "automationId": "chat_message_list.qt_scrollarea_viewport.chat_bubble_item_view", "rectangle": "(L671, T413, R1200, B488)"},
|
||||
{"name": "文件传输助手", "type": "Edit", "automationId": "chat_input_field", "rectangle": "(L691, T594, R1184, B673)"},
|
||||
{"name": "", "type": "ToolBar", "automationId": "tool_bar_accessible", "rectangle": "(L679, T673, R1192, B717)"}
|
||||
]
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Date: Sat, 19 Sep 2026 04:16:44 GMT
|
||||
Server: Kestrel
|
||||
Cache-Control: no-store
|
||||
Transfer-Encoding: chunked
|
||||
X-Correlation-Id: 56cc6ebfac8f4c59b26ca9e832149e8f
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"items":[{"fingerprint":"6b2c72487f9a1e179d0b4f2bb8d50038a683b3a5c9d7404aae9cbe1ef2356923","type":"Text","sender":null,"summary":"wxagent-smoke-20260918161447-254c4428e37c46c996c0fa4af0841a55","content":null},{"fingerprint":"8a50e9216c22a893332c8458979bdb9d4a45aa23a8dea1d36199fcf60c2c4aee","type":"Text","sender":null,"summary":"ome[WxAgent验证] UI 单 Client 发送验证 20260919-0239","content":null},{"fingerprint":"0c62388df1125439daf09f1911bb7d3aa27b1b1fb0ecba4d6f49fda74de37567","type":"Text","sender":null,"summary":"[WxAgent验证] 单 Client 多对象广播 20260919-0328","content":null},{"fingerprint":"837b6ef9c70f1ddfa462cc9d973b312e71935539a8e493c519b9099de0fc6c86","type":"Text","sender":null,"summary":"[WxAgent验证] 单 Client 多对象广播修复验收 20260919-0412","content":null}],"limit":50,"offset":0,"hasMore":false,"nextOffset":null}
|
||||
@@ -0,0 +1,10 @@
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Date: Sat, 19 Sep 2026 04:16:50 GMT
|
||||
Server: Kestrel
|
||||
Cache-Control: no-store
|
||||
Transfer-Encoding: chunked
|
||||
X-Correlation-Id: ec106963f1be4f45b3e5d9b950e8997d
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"items":[{"fingerprint":"6b2c72487f9a1e179d0b4f2bb8d50038a683b3a5c9d7404aae9cbe1ef2356923","type":"Text","sender":null,"summary":"wxagent-smoke-20260918161447-254c4428e37c46c996c0fa4af0841a55","content":null},{"fingerprint":"8a50e9216c22a893332c8458979bdb9d4a45aa23a8dea1d36199fcf60c2c4aee","type":"Text","sender":null,"summary":"ome[WxAgent验证] UI 单 Client 发送验证 20260919-0239","content":null},{"fingerprint":"0c62388df1125439daf09f1911bb7d3aa27b1b1fb0ecba4d6f49fda74de37567","type":"Text","sender":null,"summary":"[WxAgent验证] 单 Client 多对象广播 20260919-0328","content":null},{"fingerprint":"837b6ef9c70f1ddfa462cc9d973b312e71935539a8e493c519b9099de0fc6c86","type":"Text","sender":null,"summary":"[WxAgent验证] 单 Client 多对象广播修复验收 20260919-0412","content":null}],"limit":50,"offset":0,"hasMore":false,"nextOffset":null}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"sourceFiles": [
|
||||
"messages-filehelper.response.json",
|
||||
"messages-jixiang.response.json"
|
||||
],
|
||||
"query": "GET /api/v1/messages?accountId=<bound-account>&session=<session-name>&limit=50&includeContent=false",
|
||||
"contentWasStored": false,
|
||||
"marker": "[WxAgent验证] 单 Client 多对象广播修复验收 20260919-0412",
|
||||
"filehelper": {
|
||||
"itemCount": 4,
|
||||
"markerFoundInSummary": true,
|
||||
"allContentFieldsNull": true,
|
||||
"lastMessageFingerprint": "837b6ef9c70f1ddfa462cc9d973b312e71935539a8e493c519b9099de0fc6c86"
|
||||
},
|
||||
"jixiang": {
|
||||
"itemCount": 4,
|
||||
"markerFoundInSummary": true,
|
||||
"allContentFieldsNull": true,
|
||||
"lastMessageFingerprint": "837b6ef9c70f1ddfa462cc9d973b312e71935539a8e493c519b9099de0fc6c86"
|
||||
},
|
||||
"interpretation": "The raw read-only responses contain the unique test marker in summary and omit full message bodies; the matching final fingerprint is an independent post-send read-back signal for both target sessions."
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
HTTP/1.1 409 Conflict
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Date: Sat, 19 Sep 2026 04:25:03 GMT
|
||||
Server: Kestrel
|
||||
Cache-Control: no-store
|
||||
Transfer-Encoding: chunked
|
||||
X-Correlation-Id: 78820fff9db246feb032a873018d43bb
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"kind":"send-text","accountId":"a2e8a1eaab7fd5fbd3806525c0d9cce750c28f4efb8e7cfcabc9e3e8660e0277","targetId":"session_item_吉祥三宝","text":"[WxAgent验证] 不应发送","idempotencyKey":"wxagent-single-20260919-confirmation-negative","confirmed":false}
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"correlationId":"78820fff9db246feb032a873018d43bb","error":{"code":"ConfirmationRequired","message":"Explicit send confirmation is required.","stage":"request","retry":false}}
|
||||
@@ -0,0 +1,10 @@
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Date: Sat, 19 Sep 2026 04:16:35 GMT
|
||||
Server: Kestrel
|
||||
Cache-Control: no-store
|
||||
Transfer-Encoding: chunked
|
||||
X-Correlation-Id: fd1f07e563774a238c1da3d85ccdf470
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'
|
||||
@@ -0,0 +1 @@
|
||||
{"items":[{"name":"吉祥三宝","automationId":"session_item_吉祥三宝","isCurrent":false},{"name":"文件传输助手","automationId":"session_item_文件传输助手","isCurrent":true},{"name":"运营3部日报","automationId":"session_item_运营3部日报","isCurrent":false},{"name":"李晓敏","automationId":"session_item_李晓敏","isCurrent":false},{"name":"杨礼溪","automationId":"session_item_杨礼溪","isCurrent":false},{"name":"\uD83C\uDF3B2026级初一5班家长群","automationId":"session_item_\uD83C\uDF3B2026级初一5班家长群","isCurrent":false},{"name":"外呼机器人研发对接","automationId":"session_item_外呼机器人研发对接","isCurrent":false},{"name":"商务通系统对接问题反馈","automationId":"session_item_商务通系统对接问题反馈","isCurrent":false},{"name":"潘卫东-潘总、刘猛、邵存阳-邵总、根成、高总公司-潘卫东、min","automationId":"session_item_潘卫东-潘总、刘猛、邵存阳-邵总、根成、高总公司-潘卫东、min","isCurrent":false}],"limit":20,"offset":0,"hasMore":false,"nextOffset":null}
|
||||
@@ -0,0 +1,10 @@
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Date: Sat, 19 Sep 2026 04:16:38 GMT
|
||||
Server: Kestrel
|
||||
Cache-Control: no-store
|
||||
Transfer-Encoding: chunked
|
||||
X-Correlation-Id: a5655c213ccd4d82a4b761200618269b
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'
|
||||
@@ -0,0 +1 @@
|
||||
{"items":[{"name":"吉祥三宝","automationId":"session_item_吉祥三宝","isCurrent":false},{"name":"文件传输助手","automationId":"session_item_文件传输助手","isCurrent":true},{"name":"运营3部日报","automationId":"session_item_运营3部日报","isCurrent":false},{"name":"李晓敏","automationId":"session_item_李晓敏","isCurrent":false},{"name":"杨礼溪","automationId":"session_item_杨礼溪","isCurrent":false},{"name":"\uD83C\uDF3B2026级初一5班家长群","automationId":"session_item_\uD83C\uDF3B2026级初一5班家长群","isCurrent":false},{"name":"外呼机器人研发对接","automationId":"session_item_外呼机器人研发对接","isCurrent":false},{"name":"商务通系统对接问题反馈","automationId":"session_item_商务通系统对接问题反馈","isCurrent":false},{"name":"潘卫东-潘总、刘猛、邵存阳-邵总、根成、高总公司-潘卫东、min","automationId":"session_item_潘卫东-潘总、刘猛、邵存阳-邵总、根成、高总公司-潘卫东、min","isCurrent":false}],"limit":20,"offset":0,"hasMore":false,"nextOffset":null}
|
||||
@@ -0,0 +1,10 @@
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Date: Sat, 19 Sep 2026 04:16:40 GMT
|
||||
Server: Kestrel
|
||||
Cache-Control: no-store
|
||||
Transfer-Encoding: chunked
|
||||
X-Correlation-Id: 7c10f8eacba04e4ca13cbc896379e177
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'
|
||||
@@ -0,0 +1 @@
|
||||
{"items":[{"name":"吉祥三宝","automationId":"session_item_吉祥三宝","isCurrent":false},{"name":"文件传输助手","automationId":"session_item_文件传输助手","isCurrent":true},{"name":"运营3部日报","automationId":"session_item_运营3部日报","isCurrent":false},{"name":"李晓敏","automationId":"session_item_李晓敏","isCurrent":false},{"name":"杨礼溪","automationId":"session_item_杨礼溪","isCurrent":false},{"name":"\uD83C\uDF3B2026级初一5班家长群","automationId":"session_item_\uD83C\uDF3B2026级初一5班家长群","isCurrent":false},{"name":"外呼机器人研发对接","automationId":"session_item_外呼机器人研发对接","isCurrent":false},{"name":"商务通系统对接问题反馈","automationId":"session_item_商务通系统对接问题反馈","isCurrent":false},{"name":"潘卫东-潘总、刘猛、邵存阳-邵总、根成、高总公司-潘卫东、min","automationId":"session_item_潘卫东-潘总、刘猛、邵存阳-邵总、根成、高总公司-潘卫东、min","isCurrent":false}],"limit":20,"offset":0,"hasMore":false,"nextOffset":null}
|
||||
@@ -0,0 +1,30 @@
|
||||
3ad3c85c315c6f6d831b3d84f894a3cd34ba237b8ba0d8401d814f8beb6be75a broadcast-get.http.txt
|
||||
4e01ccec54fa1fd023d150d84ee45c698aa5a08cce4b20048ee6a3d84d41336d broadcast-get.response.json
|
||||
0de4d771c51fb7f812c3521771cf8126dd015a90f2cfe7efa07b64431993b72b broadcast-replay.http.txt
|
||||
4e01ccec54fa1fd023d150d84ee45c698aa5a08cce4b20048ee6a3d84d41336d broadcast-replay.response.json
|
||||
390c3db2dbbbd40886125c41a308c0fd09de34a893abd1594f62e031fb85d834 broadcast.request.json
|
||||
edaf2a0fd912158a64600afea898ef7e92e1f952b99e8f50dcdf23aff5e3fe73 broadcast-submit.http.txt
|
||||
8889cbed1f14be4f767cdc3a0ee372f75ba2982e6dba4f53504a98907d9406b2 broadcast-submit.response.json
|
||||
f0c05ef72bab694caf2d890bfc0fb6fd69fd01717c4b24365d6bb34dc50ef571 capabilities.http.txt
|
||||
ba09345de35f48ed812cbe54e6298c68f127c0b9cea6ee426e21c3669b16bb04 capabilities.response.json
|
||||
af5e1cd3d73f4f332a8a32bda24bbc814ab0d90e85ecf6eed6b0b4585be269e9 confirmation-gate.http.txt
|
||||
4dcde0d485bb221a4846cc53e225f05bb944433c939f5b7595c3a1ff700b9f82 confirmation-gate.request.json
|
||||
fc0cec0c57504482651dc664903eef4d493a39c12357504282bfa58266388455 confirmation-gate.response.json
|
||||
529430b446c9b8b1d05c7fcb51514e8ec1b71627af5ffe1c30d29791c83fa008 mcp-ui-evidence.json
|
||||
64bc614875c15a7ab488fa9740bab0f606c9234596a5e903a88d2e68e22ca8b4 messages-filehelper.http.txt
|
||||
b825e65ba2f3f5d27817ef64273785cb9be09cf9df8dfde6afe01794659f7994 messages-filehelper.response.json
|
||||
63fceae775c345adc899b29b0a39d72906a662ba58a20eccea34cd0d6116f842 messages-jixiang.http.txt
|
||||
b825e65ba2f3f5d27817ef64273785cb9be09cf9df8dfde6afe01794659f7994 messages-jixiang.response.json
|
||||
54c40a6e30b2dbaa50f8027727b7aeb22cedc4998177c3fe350a44f17e155816 readback-summary.json
|
||||
623571c8a2bd35f089906e8587c01d5db157e2af5d8b908bcf26d39e0c9b7380 README.md
|
||||
344b3852dec53fc2b927669b5643863c7a4c184f2ac41d99374e6f16a83ff53e send-confirmation-gate.http.txt
|
||||
86ed9bc17d74b0ccf463b6519e25df576520b263b4d16eda79864b7500681cc3 send-confirmation-gate.request.json
|
||||
e2e07ecbbdd276f71e78dfe9160abb04d2bef923b73ae8b0b21eed759806461f send-confirmation-gate.response.json
|
||||
dc0821a7b6f37f314e7fcd2aa8d68e96c27805cf0fea8e0cb03517f36ecea247 sessions-1.http.txt
|
||||
976c98db5de557fffd1a7d8ba6c937925d791da4df6b5f6838983c09b4253f9b sessions-1.response.json
|
||||
843811528eb530326e7d49b4be3fffbb11ad89cd2882232221ff6dca61dcbb4e sessions-2.http.txt
|
||||
976c98db5de557fffd1a7d8ba6c937925d791da4df6b5f6838983c09b4253f9b sessions-2.response.json
|
||||
b0499282b98c3bf946c53698a8dcf8de830396a8e9d42b38451168d8c3dcf554 sessions-3.http.txt
|
||||
976c98db5de557fffd1a7d8ba6c937925d791da4df6b5f6838983c09b4253f9b sessions-3.response.json
|
||||
fc2fa5ecff7f2c9ad9c71842b725d78d4f999c283e11832989f10bc7fbc910a0 status.http.txt
|
||||
0280b1df77f973805bb487506002eac4e3ec2d67c8d68d58c1603f9b93e33eca status.response.json
|
||||
@@ -0,0 +1,10 @@
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Date: Sat, 19 Sep 2026 04:22:44 GMT
|
||||
Server: Kestrel
|
||||
Cache-Control: no-store
|
||||
Transfer-Encoding: chunked
|
||||
X-Correlation-Id: acfbaa6b604646268b3892d050e8a4aa
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'
|
||||
@@ -0,0 +1 @@
|
||||
{"serviceOnline":true,"wechatAvailable":true,"sessionAvailable":true,"sessionLocked":false,"windowFound":true,"errors":[],"wechatVersions":["4.1.13.65"],"activeAccountBound":true,"defaultReadOnly":true}
|
||||
Reference in New Issue
Block a user