Skip to content

快速开始

返回总览

这一页只处理两件事

  • 先跑通一条最小 workflow
  • 再判断什么时候该切到 createWorkflowKit

这套库解决什么问题

clack-kit 把终端交互流程整理成一条可读、可复用、可恢复的工作流

第一阶段只需要关心三样东西

  • workflow 的 id
  • steps 的顺序
  • result.values 里的最终输入

命令执行、CLI 参数、历史复用、断点恢复和日志留档都可以后加,不必在第一步全部接上

先跑一个最小例子

ts
import { defineStep, runWorkflowSafely } from 'clack-kit';

const result = await runWorkflowSafely({
  id: 'hello-workflow',
  steps: [
    defineStep.text({
      id: 'name',
      message: '项目名',
      required: true,
    }),
    defineStep.autocomplete({
      id: 'framework',
      message: '框架',
      options: ['react', 'vue', 'svelte'],
    }),
  ],
});

if (!result) return;

console.log(result.values.name);
console.log(result.values.framework);

先记住这三个点

  • runWorkflowSafely 在取消时返回 null
  • steps 从上到下执行
  • 输入类步骤的结果写进 result.values

什么时候切到 createWorkflowKit

runWorkflow 和 runWorkflowSafely 适合单条轻量流程

出现下面任一情况时,再切到 createWorkflowKit

  • 多条 workflow 需要复用配置
  • 需要显式打开 history、checkpoint、logs
  • 需要统一的 ASCII banner 或 task-log 默认值
  • 需要替换 renderer 或 executor
  • 需要插件和额外的 context.tools
ts
import {
  createWorkflowKit,
  defineStep,
  defineSteps,
  defineWorkflow,
} from 'clack-kit';

const kit = createWorkflowKit({
  asciiArt: {
    font: 'Standard',
  },
  id: 'create-project',
  taskLog: {
    limit: 20,
  },
});

const workflow = defineWorkflow({
  id: 'create-project',
  intro: '创建项目',
  outro: (context) => `项目流程结束:${String(context.values.name)}`,
  steps: defineSteps([
    defineStep.text({
      id: 'name',
      message: '项目名',
      required: true,
    }),
    defineStep.multiselect({
      id: 'features',
      message: '基础能力',
      options: ['eslint', 'vitest', 'docker'],
      required: true,
    }),
    defineStep.command({
      id: 'prepare',
      title: '准备模板',
      async run(context, io) {
        io.stdout(`preparing ${String(context.values.name)}\n`);
        await io.sleep(300);
        return { prepared: true };
      },
    }),
  ]),
});

const result = await kit.runSafely(workflow, {
  initialValues: {
    name: process.env.PROJECT_NAME,
  },
});

if (!result) return;

console.log(result.values.name);
console.log(result.results.prepare);

这时会多出第二个结果容器

  • values 保存输入和值快照
  • results 保存步骤显式返回的业务产物

如果要输出统一的 ASCII banner,就在 createWorkflowKit() 上配置 asciiArt

  • asciiArt.title 会先走 figlet
  • asciiArt.artTitle 会直接输出
  • 两者都没给时,会回退到 id

默认为什么不启用持久化

很多流程只需要问几个问题、跑几个命令、拿到结果,然后结束

这类场景默认写入历史、checkpoint 和日志,收益不高,复杂度却会上来

因此默认行为很直接

  • history 关闭
  • checkpoints 关闭
  • logs 关闭

只有显式开启后,.clack-kit 才会产生持久化文件

需要时再打开 history、checkpoint 和 logs

ts
const kit = createWorkflowKit({
  checkpoints: true,
  history: true,
  logs: true,
});

const result = await kit.runSafely(workflow, {
  checkpoint: {
    resume: 'ask',
    save: true,
  },
  history: {
    reuse: 'ask',
    saveSnapshot: true,
  },
});

三者分工很清楚

  • history 负责复用上一份输入快照
  • checkpoint 负责从中断位置继续执行
  • logs 负责保存本次运行的事件和输出

默认落盘位置是

txt
.clack-kit/
  checkpoints.json
  history.json
  logs/

下一步建议