@cofold/commands

中文文档
0.3.0发布于 2026/10/06MITTypeScriptES Module构建来源已验证近 30 天下载 2740

一个命令是数据:声明,注册,输入, argv语法,强迫和计划,由每个表面得到.

中文使用文档
文档目录15 节
  1. 这是什么
  2. 一个计划
  3. 一个动作,几个表面
  4. 能力
  5. 软件包
  6. 试试看
  7. 一个声明,三个表面
  8. 当地CLI
  9. 服务器提供的命令
  10. 将 OpenAPI 文档转换为 CLI
  11. 实例
  12. 文档中的命令
  13. 文档
  14. 为什么
  15. 许可证

@ cofold/ 命令

宣布一个命令一次。 到处跑.

npm node types dependencies license

指令框架 复数 家族: 此软件包是声明、 注册和输入每个表面共享; 表面列在下面 软件包,除生成的参考文献外,所有参考文献都是兄弟般的软件包.

这是什么

@cofold/commands 是一个 TypeScript 命令框架,其中命令是可重复使用的定义,而不是只使用 CLI 处理器.

同样的声明可以通过CLI,HTTP端点,一个MCP工具来被曝光,生成文档, shell补全,代理发报技能,或者其他适配器而不重新定义其输入和行为.

const registry = createRegistry()
  .provide("config", {
    resolve: () => loadConfig(),
  })
  .provide("store", {
    deps: ["config"],
    resolve: ({ config }) => open(config.path),
    dispose: (store) => store.flush(),
  });

registry.action({
  id: "note.list",
  summary: "List notes, newest first",

  needs: ["store"],

  input: {
    status: {
      type: "string",
      enum: ["open", "done"],
      description: "Only this status",
      cli: { short: "-s", value: "STATUS" },
    },

    limit: {
      type: "integer",
      minimum: 1,
      default: 20,
      description: "How many",
      cli: { short: "-n", value: "N" },
    },
  },

  surfaces: {
    cli:  { pattern: ["note", "list"] },
    http: { method: "GET", path: "/notes" },
    mcp: true,
  },

  run: ({ input, store }) =>
    output(store.all(input.status).slice(0, input.limit)),
});

registry.action({
  id: "note.add",
  summary: "Add a note",

  needs: ["store"],

  input: {
    title: {
      type: "string",
      minLength: 1,
      maxLength: 120,
      description: "What the note says",
    },

    status: {
      type: "string",
      enum: ["open", "done"],
      default: "open",
      description: "Where it starts",
      cli: { short: "-s", value: "STATUS" },
    },
  },
  required: ["title"],

  surfaces: {
    cli:  { pattern: ["note", "add", ":title"] },
    http: { method: "POST", path: "/notes" },
    mcp: true,
  },

  run: ({ input, store }) => output(store.add(input)),
});

每个表面没有单独的指令定义.

flowchart TD
  action(["action"])
  action --> cli["CLI"]
  action --> http["HTTP"]
  action --> mcp["MCP"]
  cli --> help["help"]
  cli --> docs["docs"]
  cli --> completion["completion"]

行动仍是一个平庸的目标。 不同部分 @cofold/commands 决定如何曝光.

一个计划

input 是对输入的语法描述,也是规则的唯一说明.

title:  { type: "string",  minLength: 1, maxLength: 120 }
status: { type: "string",  enum: ["open", "done"], default: "open" }
limit:  { type: "integer", minimum: 1, default: 20 }

CLI用它来解析和胁迫论点. HTTP使用它来验证请求. MCP作为工具的输入计划出版. 文档得到相同的默认,语句,描述和制约.

因此,一条规则以同样的方式执行,无论走哪条路:

notes note add ""                     # title must be 1 to 120 characters
curl -X POST /notes -d '{"title":""}' # 400 title must be 1 to 120 characters
note_add({ status: "later" })         # isError: status must be one of open, done

TypeScript 也从中获取处理器输入 :

input.title  // string
input.status // "open" | "done"
input.limit  // number

规则只有一份要更正.

一个动作,几个表面

从上面的声明, @cofold/commands 可以提供:

表面结果
notes note list -s open -n 5解析和强制CLI输入
notes note add "Ship it"插槽、默认和长度
GET /notes?status=open对 HTTP 的相同动作
POST /notes相同的验证,答复如下: 400
notes note list --json稳定的机器可读输出
notes note list --quiet脚本纯输出
notes note add --help生成的使用、 选项、 默认和enums
notes note <TAB>外壳补全
notes docs生成了 Markdown 引用
notes skill代理向导命令引用
note_list, (中文(简体) ), note_addMCP 工具由相同的输入方案支持

增加表面并不意味着增加另一个执行.

surfaces: {
  cli:  { pattern: ["note", "add", ":title"] },
  http: { method: "POST", path: "/notes" },
  mcp: true,
}

如果一个表面没有被宣布,则该动作不会在那里被暴露出.

一项行动也可以说它做什么,对什么: effect 实值 read, (中文(简体) ), add, (中文(简体) ), change 或者说 remove,以及 resource 名称 。 每个表面读取相同的两个字段:参考打印出它们,MCP取出它的提示,终端先问一个 remove,而清单的客户端会绘制一个列表,一个创建和项目动作.

能力

行动可以宣布它们需要什么,而不是自己建立依赖关系.

通常的案例是一个经过认证的客户端,其中一半的程序需要,没有人想再建设两次.

const registry = createRegistry()
  .provide("config", {
    resolve: () => loadConfig(),
  })
  .provide("api", {
    deps: ["config"],
    resolve: ({ config }) => createClient({
      baseUrl: config.url,
      token: config.token,
    }),
    dispose: (api) => api.close(),
  });

然后说:

registry.action({
  id: "case.show",
  needs: ["api"],

  input: {
    id: { type: "string", minLength: 1 },
  },
  required: ["id"],

  surfaces: {
    cli: { pattern: ["case", "show", ":id"] },
    mcp: true,
  },

  run: ({ input, api }) => output(api.get(`/cases/${input.id}`)),
});
flowchart LR
  config["config"] -->|deps| api["api"]
  api -->|needs| run["run"]
  run -.->|dispose| close["api.close"]

能力在操作员运行前按依赖顺序解决,并可以依赖其他能力. 任何打开的,无论处理者返回还是扔出,都会被处理掉.

没有为不要求它的行动构建任何结构,所以一个在糟糕的参数上失败的命令永远不会打开连接.

这样可以保持动作声明性,而不会把登记册变成一个全球范围的一包物体.

软件包

每个地表一个包,每个包有一个入站点(@cofold/mcp 3),但生成的引用除外,这是此软件包的 ./docs 进入点.

软件包目的
@cofold/commands行动、计划、能力、登记 没有终极知识.
@cofold/terminal解析、帮助、完成、产出合同和退出代码
@cofold/mcp在没有 MCP SDK 依赖性的情况下将动作曝光为 MCP 工具
@cofold/mcp/stdio把这些工具放在Stdio上 还是没有SDK,还是没有依附关系
@cofold/mcp/server可选 SDK 支持的可流式 HTTP,用于在已有服务器中安装
@cofold/commands/docs为人员和代理人生成Markdown引用
@cofold/remote从远程列表或 OpenAPI 实现命令
@cofold/yaml将 YAML 子集分析为纯数据, 并有源代码错误
@cofold/config查找配置文件, 并显示哪个值来自

还有 零运行时间依赖关系 每个软件包中,包括一个工作中的 MCP 服务器: npm install @cofold/commands @cofold/terminal 安装两个软件包而不安装其他软件包. @cofold/mcp/server 是单一的例外,并且是选入的,因为可流式HTTP值SDK,而stdio则不值. 它宣布官方的MCP SDK是一个可选的对等方,所以除非您提出要求,否则没有安装它.

验证为可选用途 标准Schema,因此Zod, Valibot 和 ArkType 等库可以不用 @cofold/commands 取决于其中任何一个.

试试看

pnpm install
pnpm examples

一个声明,三个表面

node examples/commands/dist/petshop/cli.js pet add Rex -a 3 -b corgi

# see the MCP tools an agent receives
node examples/commands/dist/petshop/cli.js mcp tools

# expose the same actions over HTTP
node examples/commands/dist/petshop/cli.js serve --port 8799 &

curl -X POST localhost:8799/pets \
  -d '{"name":"Ada","age":99}'

当地CLI

node examples/commands/dist/kitchen-sink/cli.js note add "Ship cofold" -t work
node examples/commands/dist/kitchen-sink/cli.js note list

# generate the agent-facing reference
node examples/commands/dist/kitchen-sink/cli.js skill

服务器提供的命令

node examples/commands/dist/clerver/cli.js serve --port 8787 &

node examples/commands/dist/clerver/cli.js pet list
node examples/commands/dist/clerver/cli.js pet add Rex --species dog --age 3

将 OpenAPI 文档转换为 CLI

API不需要知道这一点 @cofold/commands 已存在.

# any server that answers the document. clerver happens to be one
node examples/commands/dist/clerver/cli.js serve --port 8793 &

node examples/commands/dist/open-cli/cli.js \
  --spec examples/samples/petstore.json \
  pets --limit 2

实例

资料库包括四个工作实例: examples/commands数字 :

示例显示
petshop通过CLI、HTTP和MCP暴露出一组动作
kitchen-sink本地 CLI 特性集
clerver从远程服务器上发现的命令
open-cli从现有的 OpenAPI 文档建立 CLI

文档中的命令

命令已经从这个库没有写的两个文档运抵这里:远程清单和OpenAPI规格. 一个YAML或JSON文件是第三次的同一种接合,它就是将"命令是数据"从一个债权变成一个被证明的财产.

document -> ActionDefinition -> registry -> CLI / HTTP / MCP

除一件事外,文档定义的命令需求已经存在. run 是函数,一个文件不能持有一个,所以执行被声明为数据:已命名的执行者和命令步骤列表.

commands:
  release.deploy:
    summary: Deploy the application

    input:
      env: { type: string, enum: [staging, production], default: production, cli: { short: -e } }

    surfaces:
      cli: { pattern: [release, deploy] }

    run:
      - exec: { command: ./scripts/deploy.sh, args: ["{env}"] }

input jSON Schema的同一张地图 registry.action 带和 surfaces 是一个相同的声明,所以终端,一个HTTP请求和一个MCP工具调用,完全按照代码中的规则进行.

读这些的前端是 s2cmd,一个包自己的。 文件作者得到验证,帮助,完成, --json,一个生成的引用,HTTP路由和MCP工具,不执行任何这些表面,也不写一个处理器. 它的 README 记录执行者,插值规则,以及为什么一个运行一个进程的文档默认不是一个代理工具.

文档

全部的手动生活在这里 docs/commands/。 。 。 .

以 :

还没建成的,还有问题还没解决 ROADMAP.md。 。 。 .

为什么

不是因为分析很困难 解析是解决的部分.

选择任何维持了一年的程序,并计算行数 关于 其命令对应的线条 :

  • 装入配置文件, 以及其中的配置文件或目标
  • 证书,绝不打印为错误
  • --json 保持稳定, --quiet 打印一个标识符
  • 一个脚本可以打开的退出代码
  • 当有东西被吸入时读取 stdin
  • NO_COLOR, TTY 检测,终端宽度
  • 完成时知道这个安装的id, 不只是旗名
  • 仍然真实的参考文档
  • 而现在的MCP工具, 对于将驱动它的代理

解析器给你第一行的第一分之三. 之后的一切,每个程序都再次写作.

大多数 CLI 库也将命令声明作为设置进程的一部分:

program
  .command("note list")
  .option("-s, --status <status>")
  .action(handler);

描述是交给建设者的字符串,行为是关闭. 接完电话就回电了 询问:任何知道命令存在的物体,它需要什么,它意味着什么,或者它需要什么. 因此帮助漂移,因为用词行就是评论和评论的烂掉. 交叉行为无处可去 所以 --json 每个动作都会被再次写入,其中一人会打印出一个流浪者 console.log. 没有任何内容可以检查,因为没有登记册可以检查.

当终端是唯一的消费者时,这效果很好.

一旦终端不是唯一的呼叫者,它就停止工作。 一个打出的命令,一个HTTP请求和一个MCP工具调用是同一个调用:相同的参数,相同的默认,相同的验证. 只有他们到达的方式是不同的.

每平面申报,协议写出多次并维持多次. 一份副本漂移的一天,一个代理被显示一个规则,请求从未被持有,一个在终端被执行的绑定从API中缺失.

召者已出已来为人. 特工必须被告知 命令接受什么 作为计划, 它可以调用任何东西。 资料 .action(handler) 丢弃正是代理时代需要保存的信息.

@cofold/commands 保持信息活着.

const action = {
  id: "note.list",
  input: { /* ... */ },
  surfaces: { /* ... */ },
  run: handler,
};

国家行动倡议是这一行动的一种观点.

HTTP也一样.

MCP也一样.

成本是对处理器的一种限制:处理器收到一个犬形输入对象并返回一个值,而不是读取 process.argv 和印刷。 这就是整个纪律,其他一切从它开始, 因为一个从不触及终端的操作员 可以用一个不是终端的东西来操作.

@cofold/mcp 这是测试。 一个完整的MCP表面,JSON Schema世代包含,没有依赖性,因为它没有什么可以发明的:动作已经知道. @cofold/mcp/stdio 是读取的回路, 并且它是手写的,同样的原因 YAML 子集是 - 新线限制的 JSON- RPC 在两个管子上不值得一个网络框架.

命令是数据。 界面为适配器.

许可证

版权:QQ 2026 Softov.

凭 MIT 许可证。 。 。 .

版本与发布记录

@cofold/commands 共发布 4 个版本,首次发布于 2026/09/23;过去 12 个月发布了 4 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.3.0latest2026/10/061 个月前
0.2.22026/09/271 个月前
0.2.12026/09/271 个月前
0.2.02026/09/231 个月前

关于 @cofold/commands 的常见问题

@cofold/commands 是什么?

一个命令是数据:声明,注册,输入, argv语法,强迫和计划,由每个表面得到.

如何安装 @cofold/commands?

在项目目录运行 npm install @cofold/commands,或使用 pnpm add / yarn add / bun add。

@cofold/commands 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cofold/commands 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@cofold/commands 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@cofold/commands 可以商用吗?

@cofold/commands 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cofold/commands 的下载量有多少?

根据 npm 官方下载统计,@cofold/commands 在 2026/10/10 – 2026/11/08 这 30 天内被下载 2,740 次,日均约 91 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cofold/commands 还在维护吗?

最新版本 0.3.0 发布于 2026/10/06(1 个月前);至今共发布 4 个版本,其中过去 12 个月发布了 4 个;首次发布于 2026/09/23。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。