Api Integration
指导前端与后端API集成的类型、错误、鉴权及实时通信设计规范。
下载 255
定义一次命令,自动部署至CLI、API和MCP,确保接口一致性。
openclaw skills install @ianderrington/universal-command命令、参数、文件名以原文为准
定义一次,随处部署。 CLI、API 和 MCP 接口的统一源。
如果你正在为 Supernal 构建命令,请直接使用本包。不要为 CLI、API 或 MCP 分别创建独立实现。
npm install @supernal/universal-commandimport { UniversalCommand } from '@supernal/universal-command';
export const userCreate = new UniversalCommand({
name: 'user create',
description: '创建新用户',
input: {
parameters: [
{ name: 'name', type: 'string', required: true },
{ name: 'email', type: 'string', required: true },
{ name: 'role', type: 'string', default: 'user', enum: ['user', 'admin'] },
],
},
output: { type: 'json' },
handler: async (args, context) => {
return await createUser(args);
},
});// CLI
program.addCommand(userCreate.toCLI());
// → mycli user create --name "Alice" --email "alice@example.com"
// Next.js API
export const POST = userCreate.toNextAPI();
// → POST /api/users/create
// MCP 工具
const mcpTool = userCreate.toMCP();
// → 供 AI 代理使用的 user_create 工具只需编写一次逻辑。处理器接收已验证的参数并返回结果:
handler: async (args, context) => {
// 相同代码同时适用于 CLI、API 和 MCP
return await doThing(args);
}定义一次参数 —— 验证规则、CLI 选项、API 参数和 MCP 模式将自动生成:
input: {
parameters: [
{ name: 'id', type: 'string', required: true },
{ name: 'status', type: 'string', enum: ['draft', 'active', 'done'] },
{ name: 'limit', type: 'number', min: 1, max: 100, default: 10 },
],
}在需要时可针对不同接口覆盖行为:
cli: {
format: (data) => formatForTerminal(data),
streaming: true,
},
api: {
method: 'GET',
cacheControl: { maxAge: 300 },
auth: { required: true, roles: ['admin'] },
},
mcp: {
resourceLinks: ['export://results'],
},用于多个命令的场景:
import { CommandRegistry } from '@supernal/universal-command';
const registry = new CommandRegistry();
registry.register(userCreate);
registry.register(userList);
registry.register(userDelete);
// 生成所有 CLI 命令
for (const cmd of registry.getAll()) {
program.addCommand(cmd.toCLI());
}
// 生成所有 API 路由
await generateNextRoutes(registry, { outputDir: 'app/api' });
// 生成 MCP 服务
const server = createMCPServer(registry);对于无需代码生成的简单场景:
import { createRuntimeServer } from '@supernal/universal-command';
const server = createRuntimeServer();
server.register(userCreate);
server.register(userList);
// 作为 Next.js 使用
export const GET = server.getNextHandlers().GET;
export const POST = server.getNextHandlers().POST;
// 或作为 Express
app.use('/api', server.getExpressRouter());
// 或作为 MCP
await server.startMCP({ name: 'my-server', transport: 'stdio' });了解当前调用接口类型:
handler: async (args, context) => {
if (context.interface === 'cli') {
// CLI 特定逻辑
} else if (context.interface === 'api') {
const userId = context.request.headers.get('x-user-id');
}
return result;
}测试一次,处处可用:
import { userCreate } from './user-create';
test('创建用户', async () => {
const result = await userCreate.execute(
{ name: 'Alice', email: 'alice@example.com' },
{ interface: 'test' }
);
expect(result.name).toBe('Alice');
});┌─────────────────────────────────────────┐
│ UniversalCommand 定义 │
│ name, description, input, handler │
└────────────────┬────────────────────────┘
│
┌────────┼────────┐
▼ ▼ ▼
┌─────┐ ┌─────┐ ┌─────┐
│ CLI │ │ API │ │ MCP │
└─────┘ └─────┘ └─────┘✅ 构建任何新的 Supernal 命令/工具
✅ 为已有逻辑添加 CLI 接口
✅ 向 AI 代理暴露功能(MCP)
✅ 创建具有统一模式的 REST API
❌ 简单的一次性脚本(过度设计)
❌ 与第三方集成且已有自身规范的情况
sc(supernal-coding)和 si(supernal-interface)均在底层使用 universal-command。当向这些工具添加新命令时,请将其定义为 UniversalCommand。
class UniversalCommand<TInput, TOutput> {
execute(args: TInput, context: ExecutionContext): Promise<TOutput>;
toCLI(): Command; // Commander.js Command
toNextAPI(): NextAPIRoute; // Next.js 路由处理器
toExpressAPI(): ExpressRoute;
toMCP(): MCPToolDefinition;
validateArgs(args: unknown): ValidationResult<TInput>;
}
class CommandRegistry {
register(command: UniversalCommand): void;
getAll(): UniversalCommand[];
}
function createRuntimeServer(): RuntimeServer;
function generateNextRoutes(registry: CommandRegistry, options: CodegenOptions): Promise<void>;
function createMCPServer(registry: CommandRegistry, options: MCPOptions): MCPServer;@supernal/universal-command*不要重新构建此模式。请直接使用!*
已收录 1 个 Skill