@cnc-tools/cli-kit

中文文档
0.3.3发布于 2026/11/05MITTypeScriptES Module近 30 天下载 6090

终端外观- feel for Node CLIs: 能力检测,一个小主题,一个活区域流槽,和一个相相运行的渲染器

中文使用文档
文档目录11 节
  1. 安装
  2. 入境点
  3. Clinkr 应用程序
  4. 能力
  5. 主题
  6. 流槽
  7. 阶段运行快速启动
  8. 分步骤
  9. 活动
  10. 顺序
  11. 折叠高高的核对表

@cnc-tools/cli-kit (英语)

节点CLI的终端外观-feel:能力检测,ANSI剥取,一个小主题,a live-region stream sink,以及用于多步指令的相位运行渲染器.

阶段运行显示在 TTY 上更新的检查表 :

Deploying web
  ✓ Build         bundle ready
      compiling…
  ⠹ Push          Pushing layer 3/5
      uploading…
  • Verify        pending
       sha256:3f2a… done

被取代的标签 仍然停留在他们的排 淡的历史。 当输出被管道或捕获时,运行 打印一个简单的固定框架.

工具箱唯一的运行时间依赖是 log-update,只有 stream 财务报告和审定财务报表 phase-run 切入点 装上它。 这个 clinkr 切入点 剪辑器 应用和进口 @vercel/clinkr,可选择的对等依赖;没有其他切入点.

安装

npm install @cnc-tools/cli-kit

需要节点22.19或更新. 该套装只采用无害环境管理,船舶编译了JavaScript和类型申报.

入境点

导入它给你什么
@cnc-tools/cli-kit/capsCaps, (中文(简体) ), resolveCaps, (中文(简体) ), resolveProcessCaps, (中文(简体) ), resolveStreamCaps, (中文(简体) ), resolveSettledNonInteractiveCaps
@cnc-tools/cli-kit/ansistripAnsi
@cnc-tools/cli-kit/clinkrrenderOutcome, (中文(简体) ), ui, (中文(简体) ), path, (中文(简体) ), muted, (中文(简体) ), status, (中文(简体) ), capsFor: cli- kit 寻找 Clinkr 应用程序
@cnc-tools/cli-kit/themepaint, (中文(简体) ), dim, (中文(简体) ), bold, (中文(简体) ), glyph, (中文(简体) ), renderTable, (中文(简体) ), renderResultBlock, (中文(简体) ), statusLine,文本帮助
@cnc-tools/cli-kit/streamcreateStreamSink, (中文(简体) ), runStream:活区及其非TTY合同
@cnc-tools/cli-kit/phasesPhaseEvent, (中文(简体) ), PhaseSpec, (中文(简体) ), PhaseState, (中文(简体) ), createPhaseStateStore (纯粹,不渲染)
@cnc-tools/cli-kit/phase-runstartPhaseRun, (中文(简体) ), createPhaseRun,以及框架、生命周期和尾部构件

Clinkr 应用程序

克林克解决终端,应用颜色优先,选择流,并写出JSON和一个脚本读取的内容. cli-kit画的是人们所看到的。 调用它的 renderOutcome 每个结果 render数字 :

import { muted, path, renderOutcome } from "@cnc-tools/cli-kit/clinkr";

// In a command's outcomes:
render: ({ worktreePath, slotName }) =>
  renderOutcome({ done: ["Moved to", path(worktreePath)], rows: [["Slot", slotName ?? muted("—")]] }),

传过来 ui 改为 createApplication 所以每一个错误, 克林克自己的和应用程序的 canceled 共享 听着 该布局为cli-kit自有:一双柱地沟,标签/值行取自第18栏的值, ✓ 完成的项目 结果, ! 警告者, ✗ 用于错误标题,最多5个列表项目,最多2个恢复步骤。 颜色关闭 它打印的布局没有逃生代码; 上面有颜色画出格言、 标签、 值和表格页眉 每一个部分的溪流。 当地语无法渲染出Unicode时,地语会倒回ASCII.

  • renderOutcome(content) 使结果的内容带有默认限制。 内容取自克林克 ResultContent, (中文(简体) ), 和有字符串的样式值: done,行、行和表格单元格。 表格单元格也可能是 Clinker 的 链接, { text, url }: 上面的颜色以口音的 OSC 8 超链接来显示其文本, 链接的颜色, 其 在文字上测量的栏;用彩色去掉,在管子上,它就是一个文字.
  • path(text), (中文(简体) ), muted(text),以及 status(text, tone) 是样式值: 文件系统路径, 递归文本 作为占位符, 和状态词在一个基调。 每个人为JSON和剧本读取的 保留了纯文本.
  • ui 是应用程序带有默认限制的 UI .
  • createOutcomeRenderer({ maximumListItems }) 财务报告和审定财务报表 createUi({ maximumListItems, maximumRecoverySteps }) 让你 拥有其他限制。 每个限值是一个正安全整数;其他任何投出一个 RangeError。 。 。 .

能力

每个渲染器都需要 Caps 明确并返回字符串,因此输出在测试中具有决定性.

import { resolveCaps, resolveProcessCaps, resolveStreamCaps } from "@cnc-tools/cli-kit/caps";

const caps = resolveProcessCaps(); // reads process.stdout and process.env
const stderrCaps = resolveStreamCaps(process.stderr); // for progress drawn on stderr
const testCaps = resolveCaps({ isTty: false, columns: 100, env: {} });

isTty 财务报告和审定财务报表 columns 描述你所解决的溪流。 保持低调的CLI 可读取的机器和从 stderr 上提取进度应解决顶盖 process.stderr。 。 。 .

颜色从正色降解为256和16个颜色,最后变为零. 无空 NO_COLOR 转弯 颜色脱落和分数 FORCE_COLOR。非 TTY 获得没有颜色,除非 FORCE_COLOR 问取来. 胶片 回到ASCII,当地方, LC_ALL,则 LC_CTYPE,则 LANG,不是 UTF-8;是空的 计数为未设置。 使用 resolveSettledNonInteractiveCaps() 汇的汇 终端出价未知,如回调和捕获输出等.

主题

import { renderResultBlock, renderTable, cell } from "@cnc-tools/cli-kit/theme";

console.log(renderResultBlock(caps, { kind: "success", headline: "Deployed.", body: "3 services" }));
console.log(
  renderTable({
    caps,
    columns: [
      { header: "SERVICE", width: "auto" },
      { header: "STATUS", width: "fill" },
    ],
    rows: [[cell("web"), cell("ok")]],
  }).join("\n"),
);

statusLine 使一个相行。 它的名称列垫默认为 13; 通过 nameWidth 改为 换一下.

布局测量终端单元格,而不是字符串长度. terminalWidth 将CJK和大多数emoji计为两个 单元格和结合标记为零,而截断则不会分出一个石墨. 这是一个近似: 终端对于一些emoji和模糊的width字符仍有分歧.

流槽

createStreamSink(caps, deps) 使框架被传递。 它不排序工作.

  • {\FN黑体\FS22\BORD1\SHAD0\3AHBE\4AH00\FSCX67\FSCY66\2CHFFFFFF\3CH808080}TTY: 重新绘制 a log-update 活区域,隐藏并恢复光标,并旋转所持帧 每90ms (英语). 活地重画会暂停终端自动包装, 这样一个 Stale 宽度不能留下孤行 .
  • 非 TTY 类型 : 没有动画,没有光标代码,没有重画出逃生. 换行 onOutput。 。 。 . 固定的相框写了一次,从ANSI取出. 捕获输出的主机依赖于 这个.

每一个接缝都可以注射: writer (默认通过) log-update, (中文(简体) ), clock (违约) setTimeout, (中文(简体) ), onOutput (默认写入每条流线通过) writer,所以一个作家 指向起伏器,以及 dwellMs,每个时间间隔规则 hold。默认住有一个 base 勾选; 将您自己的规则传递给慢步 :

const sink = createStreamSink(caps, {
  dwellMs: (transient, tickMs) => (transient?.startsWith("Uploading") ? tickMs * 3 : tickMs),
});

使用 runStream(caps, deps, body) 以恢复光标,即使 body 掷出.

sink.emitTransient(line) 一个非TTY水槽通过它 onOutput,而一个 TTY 槽则没有写作,所以现场区域仍然是唯一的作家. 从一个掷出 onOutput 到达呼叫者 emitTransient 同步; 通过 hold,它拒绝 回到承诺.

sink.finish(finalLines, { persist: false }) 抹去活区域 而不是持续它,a 非 TTY 槽写入未解析帧 。 仅 finalLines 已写入。 习惯 writer 执行 clear() 这条路.

阶段运行快速启动

import { startPhaseRun } from "@cnc-tools/cli-kit/phase-run";

const run = startPhaseRun({
  title: "Deploying web",
  phases: [
    { key: "build", name: "Build", label: "compiling…", detail: "bundle ready" },
    { key: "push", name: "Push", label: "uploading…", detail: "image pushed" },
    { key: "verify", name: "Verify", label: "checking health…", detail: "healthy" },
  ],
});
try {
  run.start("build");
  run.done("build");
  run.start("push");
  run.progress("push", "Pushing layer 3/5");
  run.note("sha256:3f2a… done\n");
  run.done("push");
  await run.finish({ finalLines: ["Deployed web."] });
} finally {
  await run.stop();
}

finish 解决每个阶段仍然开放。 如果你打电话 fail() 首先,失败的行保持红色 以后的阶段仍待处理. skip(key, detail?) 财务报告和审定财务报表 cancel(key, detail?) 将一行作为跳过 (单位:千美元)–)或已取消(⊖,用于中断的工作). note 将原始子进程输出输入 TTY 上的暗尾线,所以 生活区仍然是唯一的作家. startPhaseRun 还接受 caps, (中文(简体) ), writer, (中文(简体) ), clock, (中文(简体) ), onOutput, (中文(简体) ), dwellMs, (中文(简体) ), showRuntimeDetails (排列行显示 detail 转至 done, (中文(简体) ), nameWidth, (中文(简体) ), sequencing,以及 collapse。 。 。 .

过 finish({ persist: false }) 当活的检查表是短暂的 和其他的东西,例如 报告Stdout,是永久记录。 活体区域被抹去,没有固定框架 写在TTY或其他地方.

如果 TTY 旋转器在背景中失败( 抛出) writer.redraw 或拒绝 clock.sleep),运行记录了第一个出错,停止重绘,从不让它作为一个出错 无所取弃. finish 仍试图恢复已解决的框架和光标 stop 仍然试图恢复,然后用这个自旋器错误拒绝。 通过断裂恢复 写作失败,所以 finally 以上事项: stop 复试取之.

如果画第一帧扔, startPhaseRun (或 run.begin试图恢复光标, 然后抛出油漆出错,即使修复也失败. startPhaseRun 返回无会话 然后,所以快速启动 finally 从不运行; 失败后 run.begin, (中文(简体) ), run.stop() 重试 修复。 在TTY外, 扔东西 onOutput (或默认) writer.write(中文(简体) ) 从助手中同步抛出或 emit 相继出现后,就叫它浮出水面 国家进步 finally 仍在运行 stop。 。 。 .

分步骤

一个阶段 substeps 宣布一个级别的儿童行。 子步骤不筑巢: PhaseSpec 类型 拒绝子步骤 substeps,而州商店 扔一个在建筑或一个 phases-declared 事件,然后使标题和行保持不变.

活动

制作人报告这些进展 PhaseEvent编号:

活动效果
phases-declared替换标题和行集.
title-changed替换标题.
phase-started标记一行活动,带有可选标签.
phase-progress更改活动行的标签 . history: "replace" 放弃旧标签而不是保留它.
phase-notes替换一行的笔记:在其下方显示纯文本,被包而不是被切.
phase-done解决一行.
phase-skipped解决一行跳过: 它从来没有运行.
phase-cancelled解决一行已取消: 它被中断 .
phase-failed解决一行失败, 以事业为标签 .

使用 history: "replace" 用于快速变化状态,例如一步内的一个艺名. 这行的 历史仅保留您想要保存的标签, 并且一个非 TTY 运行日志不会对此进行瞬态行 .

使用 phase-notes 对于文本,阅读器需要全部内容,例如为什么一个步骤被重审. 历史和尾巴 线被切到终端宽度; 笔记包, 续行缩入两个单元格。 A 类 排行保存它的笔记 在它和解后, 他们改变不了它的状态.

顺序

默认 sequencing: "implicit" 适合线性工作流程。 每打开一个行标记 行已完成, 解决父程序会解开子程序, 而失败的子程序会失效 .

继续过去的失败的跑步,例如试跑者,应该通过 sequencing: "explicit"。 。 。 . 然后每行只能通过自己的活动解决。 启动子步骤激活待决父程序, 但是 解决不了其他问题。 失败的子步骤让其父母独自一人 finish 标记每行 打开作为跳过, 不管失败。 制作人和每家商店 制作它的活动,必须使用 同样的模式.

折叠高高的核对表

collapse: true 保持长清单短。 固定的行会变成一行 加上任何分步骤 失败或携带笔记。 待决行会隐藏其子步骤直到开始,只有活动行 扩展。 在一个活跃的行中,定居的子步骤会降低历史. 框架比终端高 仍然失去他们的上行 log-update剪辑.

如果您的工作流程已经发布 PhaseEvents, 用途 createPhaseRun({ caps, phases, deps }) 输入 事件改为 run.emit(event)。用于自定义显示,例如主机部件,使用 createPhaseStateStore 从 phases 并表达自己的观点.

版本与发布记录

@cnc-tools/cli-kit 共发布 6 个版本,首次发布于 2026/10/09;过去 12 个月发布了 6 个版本。

版本发布日期距今
0.3.3latest2026/11/054 天前
0.3.22026/11/046 天前
0.3.12026/10/2911 天前
0.3.02026/10/091 个月前
0.2.02026/10/091 个月前
0.0.0-stage2026/10/091 个月前

关于 @cnc-tools/cli-kit 的常见问题

@cnc-tools/cli-kit 是什么?

终端外观- feel for Node CLIs: 能力检测,一个小主题,一个活区域流槽,和一个相相运行的渲染器

如何安装 @cnc-tools/cli-kit?

在项目目录运行 npm install @cnc-tools/cli-kit,或使用 pnpm add / yarn add / bun add。

@cnc-tools/cli-kit 支持 TypeScript 吗?

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

@cnc-tools/cli-kit 支持 ESM 还是 CommonJS?

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

@cnc-tools/cli-kit 需要什么版本的 Node.js?

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

@cnc-tools/cli-kit 可以商用吗?

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

@cnc-tools/cli-kit 的下载量有多少?

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

@cnc-tools/cli-kit 还在维护吗?

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