Files
nodeagent/packages/protocol/src/messages.ts
T
jkooe cedc46d090 feat(v20): 版本纪律 + 发版自动化(对齐「做好版本功能 + GitHub 同步资产」)
## 一、版本功能(防新旧混用)
1. **单一版本源 + 构建注入**:根 package.json 的 version、git sha、构建时间经 esbuild
   `--define` 注入 agent;`system.info.build` 新增 `version/commit/built_at`(原有 `hash` 指纹不变)。
   开发态用 typeof 探测(未注入也不崩)。
2. **握手携带版本**:`auth_ok` 新增可选字段 `agent_version` / `build` / `protocol`(只增不减 → 旧控制端忽略即可)。
3. **能力级兼容比对**:新增纯函数 `capabilityDiff(local, remote)` ——
   - `missingOnRemote`:本地有远端没有 → **远端较旧**,提示更新被控端
   - `unknownLocally`:远端有本地没有 → **本控制端较旧**(不影响既有功能)
   控制端不比版本号而比**能力集合**:版本号可能相同而内容不同,能力集合不会骗人。
4. **CLI 体检**:`nodeagent info` / `connect` 直接显示被控端版本与能力对齐情况,
   把"调用时才炸"变成一句人话提示。

## 二、发版自动化(GitHub 资产同步)
`pnpm release <x.y.z|patch|minor|major>`:前置检查(干净/在 main/与远端同步)→ 改 7 个 package.json
→ 构建+打包 → 生成资产 → 提交打标签推送 → `gh release create` 上传。
- 资产:`agent.mjs`(**自更新载荷**)、`nodeagent-win-x64.zip`(人工安装包)、
  `latest.json`(version/commit/能力数 + 两个资产的 url 与 sha256)、`SHA256SUMS`
- `--dry-run` 无副作用演练;`--no-publish` 只到本地标签
- 能力数从 dist 动态取(避免写死漂移);刻意排除 `.github/`(缺 workflow 权限推不了)

## 三、兼容性契约文档
新增 `docs/VERSIONING.md`:semver 各位的含义、**只增不改**六条硬规则、
升级顺序建议(**先被控端**:新被控端向后兼容旧 CLI)、两条更新路径、发版流程、排查手册。

## 验证
- 单测 147 → **149**(新增 capabilityDiff 用例:远端过旧 / 本机过旧 / 完全一致 / 真实清单自比无差异)
- e2e 28 全绿;`node scripts/release.mjs 1.0.0 --dry-run` 演练通过且工作区无副作用
2026-10-04 23:54:51 +08:00

110 lines
2.9 KiB
TypeScript

import type { RpcError } from './errors.js';
/** JSON-RPC 2.0 请求信封(nodeagent 简化版)。 */
export interface RpcRequest<P = unknown> {
jsonrpc: '2.0';
/** ULID,响应回填相同 id */
id: string;
method: string;
params?: P;
}
/** JSON-RPC 2.0 成功响应。 */
export interface RpcResponse<R = unknown> {
jsonrpc: '2.0';
id: string;
result: R;
}
/** JSON-RPC 2.0 错误响应。 */
export interface RpcErrorResponse {
jsonrpc: '2.0';
id: string | null;
error: RpcError;
}
export type RpcMessage<R = unknown> = RpcResponse<R> | RpcErrorResponse;
/** 判断是否为错误响应。 */
export function isErrorResponse(msg: unknown): msg is RpcErrorResponse {
return typeof msg === 'object' && msg !== null && 'error' in msg;
}
// ---------- 握手 ----------
export interface HelloParams {
protocol: string;
client_id: string;
}
export interface ChallengeParams {
nonce: string;
expires_at: number;
}
export interface AuthParams {
client_id: string;
nonce: string;
/** psk 模式:Base64(HMAC-SHA256(pre_shared_key, nonce)) */
hmac?: string;
/** ed25519 模式:Base64(Ed25519_Sign(privkey, nonce)) */
signature?: string;
}
export interface AuthOkParams {
capabilities: CapabilityDescriptor[];
/** ed25519 模式:本次调用方实际被授权的能力(全量清单的子集) */
authorized?: string[];
/** 本次连接采用的认证模式 */
auth_mode?: 'psk' | 'ed25519';
/** v20:被控端语义化版本(新增字段,旧控制端忽略即可 → 向后兼容) */
agent_version?: string;
/** v20:被控端构建信息(指纹/提交/构建时间),供控制端做版本比对与提示 */
build?: { hash?: string; commit?: string; built_at?: string };
/** v20:被控端支持的协议版本(与 HelloParams.protocol 比对) */
protocol?: string;
}
// ---------- 调用 ----------
export interface InvokeParams {
capability: string;
args?: Record<string, unknown>;
}
/** 能力执行结果(业务层)。 */
export interface InvokeResult<T = unknown> {
status: 'ok' | 'failed';
data?: T;
error?: { name: string; message: string; data?: unknown };
}
/** 能力描述(能力清单条目)。 */
export interface CapabilityDescriptor {
name: string;
version: string;
description: string;
risk: 'low' | 'medium' | 'high';
params_schema: JsonSchema;
returns_schema?: JsonSchema;
}
/** JSON Schema 子集(见 DEVELOPMENT.md 4.3)。 */
export interface JsonSchema {
type?: 'object' | 'string' | 'integer' | 'number' | 'boolean' | 'array';
properties?: Record<string, JsonSchema>;
required?: string[];
additionalProperties?: boolean;
enum?: unknown[];
default?: unknown;
minimum?: number;
maximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
items?: JsonSchema;
minItems?: number;
maxItems?: number;
description?: string;
}