mirror of
https://github.com/WecomTeam/wecom-cli.git
synced 2026-09-14 18:23:19 +08:00
b2dfa0f1cc
架构: - 单 crate 拆分为 Cargo workspace,按职责分为三个 crate - wecom:argv 调度、服务发现、schema 命令树、指令处理、沙箱 FS - wecom-cli:入口装配、鉴权、配置与日志 - wecom-transport:传输后端、信封、端点目录、长任务轮询 命令模型: - 调用格式改为 `<service> [resource...] <method> [flags]` - 服务目录与方法 schema 由服务端下发并本地缓存 - 请求体支持 schema 命名参数、`--json`、`--set` 三种组合方式 - 新增 `--doc` / `--schema` / `--dry-run` 文档、预览与调试能力 - 新增 `--page-count` 自动分页与 `--output` / `--output-dir` 落盘 - 新增 `+` 前缀本地 helper 与内建 `schema`、`cache` 命令 鉴权: - 命令收敛为 `auth init` / `auth show`,扫码为默认接入方式 - 凭据统一存放于 credentials.enc(AES-256-GCM,0600) - 密钥优先使用系统 keyring,不可用时回退本地密钥文件 - token 失效时静默换取新 token 并重放一次请求 - 旧版凭据文件在启动时自动迁移 输出与约定: - 错误以结构化 JSON 输出到 stdout,日志与提示一律走 stderr - 明确退出码 0 成功、1 运行时错误、2 用法错误 - `--version` 输出携带发行渠道、构建时间与 commit id - 新增按天滚动的 JSON Lines 日志目录与额外请求头注入 - 新增可选配置文件 config.json,环境变量优先级高于配置文件 - `--json` / `--set` 中的非法 JSON 自动修复并输出前后对照 - 文件落盘由 schema 指令与响应类型决定,默认写入临时目录 能力与 Skills: - 新增邮件、在线表格、智能文档、微盘、媒体等服务品类 - 文档能力增强:搜索、重命名、成员权限与加入规则管理 - 内置 Skills 扩充至 14 个,改为按需引用的分层结构 工程: - 引入 lefthook 管理 Git 钩子,pnpm 升级至 11 - 补齐 library-level 与 process-level 双层 e2e 框架 - 重写开发说明与 CLI 命令参考文档 BREAKING CHANGE: - 调用格式由 `<category> <method> '<json>'` 改为服务/资源/方法路径 - 接口名与参数整体更名,脚本需按 `--help` / `--doc` 逐个核对迁移 - 品类标识调整:`msg` → `message`,`schedule` → `calendar` - `wecom-cli init` 移除,改用 `wecom-cli auth init` - `auth show --auth-status` 改为 `auth show --status` - 错误输出由 stderr 文本改为 stdout 结构化 JSON - `WECOM_CLI_LOG_FILE` 移除,改用 `WECOM_CLI_LOG_DIR`(传目录) - 移除 MCP 传输后端与 JSON-RPC 模式 - 移除 service_base_url_override、access_token 等废弃配置 - 落盘规则改变:由 schema 指令与响应类型决定,可用 `--output` 覆盖
87 lines
2.7 KiB
Rust
87 lines
2.7 KiB
Rust
// Used by config tests gated behind feature flags (custom-endpoint).
|
|
#![allow(dead_code)]
|
|
|
|
use serde_json::{Value, json};
|
|
|
|
/// 扁平协议的 `results_json` 内层字符串:`{"result": "<stringified-json>"}`。
|
|
///
|
|
/// wecom 网关把业务数据放在 `results_json` 字段里,该字段本身是 JSON 文本,
|
|
/// 内容为 `{"result": "<json-string>"}`——业务 JSON 再序列化一层。
|
|
pub fn results_json(data: &Value) -> String {
|
|
json!({ "result": serde_json::to_string(data).unwrap() }).to_string()
|
|
}
|
|
|
|
/// Build a wecom flat response body:
|
|
/// `{ "errcode": 0, "errmsg": "ok", "results_json": "<inner>" }`
|
|
pub fn api_response(data: &Value) -> String {
|
|
json!({
|
|
"errcode": 0,
|
|
"errmsg": "ok",
|
|
"results_json": results_json(data),
|
|
})
|
|
.to_string()
|
|
}
|
|
|
|
/// GatewayEnvelope request wrapping: `{"payload": "<stringified-json>"}`.
|
|
pub fn payload_wrap(data: &Value) -> Value {
|
|
json!({ "payload": serde_json::to_string(data).unwrap() })
|
|
}
|
|
|
|
/// Catalog listing: one service named "hr".
|
|
pub fn catalog_body() -> String {
|
|
api_response(&json!({
|
|
"items": [
|
|
{ "name": "hr", "description": "Human Resources" }
|
|
]
|
|
}))
|
|
}
|
|
|
|
/// Catalog with a custom single service.
|
|
pub fn custom_catalog_body(service_name: &str, description: &str) -> String {
|
|
api_response(&json!({
|
|
"items": [
|
|
{ "name": service_name, "description": description }
|
|
]
|
|
}))
|
|
}
|
|
|
|
/// Service detail for "hr": one resource "department" with method "list".
|
|
pub fn hr_service_body(service_base_url: &str) -> String {
|
|
api_response(&json!({
|
|
"description": "HR service description",
|
|
"base_url": service_base_url,
|
|
"schemas": {
|
|
"DeptListReq": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": { "type": "string", "description": "Dept ID" }
|
|
}
|
|
},
|
|
"DeptListRes": {
|
|
"type": "object",
|
|
"properties": {
|
|
"departments": {
|
|
"type": "array",
|
|
"items": { "type": "object" }
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"methods": {},
|
|
"resources": {
|
|
"department": {
|
|
"methods": {
|
|
"list": {
|
|
"path": "/department/list",
|
|
"http_method": "POST",
|
|
"description": "List departments",
|
|
"request": { "$ref": "DeptListReq" },
|
|
"response": { "$ref": "DeptListRes" }
|
|
}
|
|
},
|
|
"resources": {}
|
|
}
|
|
}
|
|
}))
|
|
}
|