关于 wokitoki
WokiToki(命令为 toki)是供 AI 在对话中调用的本地阻塞式反馈 CLI,适合需要收集多项回答或针对具体内容反馈的场景。它通过浏览器呈现问答与报告混合表单,并将按区块关联的结果 JSON 输出到标准输出。
主要功能
- 01本地浏览器交互式反馈
- 02支持问题与报告混合表单
- 03按区块 ID 关联回答
- 04突出引用与文本、图片输入
- 05结果 JSON 写入标准输出
适用场景
- 01收集多个决策点的反馈
- 02让用户针对报告段落逐项回应
- 03将回答准确关联到原文内容
- 04在仓库外保存交互文件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ upex-galaxy/ agentic-user-skills --skill wokitoki安装后在 Claude Code 中输入/wokitoki确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
cli/assets.d.tsindex.tsmarkdown.tsREADME.mdrender.tsschema.tsserver.tscli/ui/app.cssapp.jsreferences/examples.mdschema.mdsetup.md详细介绍
WokiToki(toki)
WokiToki 是一个本地、阻塞式反馈命令行工具,AI 会在对话中途调用它。它会提供一个深色网页界面,打开浏览器,等待用户回答,并在提交后向标准输出打印一条 Result JSON,供 AI 在同一轮中解析。品牌理念是“对讲机”:来回交流,每件事只回答一次。命令是 toki;所有工具输出都会写入 ~/.toki/。
此技能以用户级(全局)方式安装:它会在每个项目中自动加载,无需针对各个代码仓库单独配置。由于它写入的所有文件都位于 ~/.toki/ 下(绝不会写入当前工作目录),在任何代码仓库中运行 toki 都不会在该仓库留下任何痕迹——无需修改 .gitignore。
一切都由同一个引擎处理:规范是一组块。带有 controls 的块是问题;不带 controls 的块是报告段落;在同一份规范中混合使用二者,即可免费创建混合表单。
阶段 0——首次运行时检查二进制文件(在会话中首次调用前)
toki 以源代码形式发布,首次使用时会编译为一个全局二进制文件。首次调用前,请确保二进制文件存在;若不存在,则进行构建:
command -v toki >/dev/null 2>&1 || bun build --compile "<skill-dir>/cli/index.ts" --outfile "$HOME/.bun/bin/toki"
<skill-dir>是此技能的安装目录——用户级安装时为~/.claude/skills/wokitoki。- 对于 Bun 安装,
~/.bun/bin已位于 PATH 中,因此刚构建的toki可立即运行。 - 备用方案(如果
--compile不可用,或无法写入二进制文件):通过bun "<skill-dir>/cli/index.ts" <specPath>从源代码运行——行为相同,只是冷启动较慢。
首次运行的完整详情(大小、PATH、重新构建)→ references/setup.md。
何时使用 WokiToki、AskUserQuestion 或行内文本
| 情况 | 使用 |
|---|---|
| 选择 1–2 个选项、单个是/否问题、≤3 个简单决策 | AskUserQuestion |
| 同时有 >3 个决策点(混合单选、多选和开关) | WokiToki |
| 用户可能想逐点回应的长篇多章节说明/报告 | WokiToki |
| 你需要让回复与其所针对的准确短语对应 | WokiToki(高亮引用) |
| 非交互式场景/CI/没有人在浏览器前操作 | 两者都不用——输出纯文本 |
为什么不选其他方案:
AskUserQuestion的上限约为(4 个问题 × 每题 4 个选项),受终端限制,没有丰富的自由文本输入,也无法在用户作答时显示参考内容。- 行内文本问卷会产生无法明确对应内容的回复:AI 必须猜测回复中的每句话对应哪个段落/要点。WokiToki 会返回按稳定
id标记的各块答案,因此可以准确映射。
规范结构简述
{
"title": "Auth plan — decisions", // required, non-empty
"intro": "Optional markdown at top", // optional
"submitLabel": "Submit answers", // optional (default "Submit")
"blocks": [ // required, non-empty
{
"id": "q1", // required, unique within the spec
"content": "Which token strategy?", // markdown string (may be empty "")
"controls": { // OMIT for a report paragraph
"type": "single", // single | multi | toggle
"options": [ // required for single/multi, FORBIDDEN for toggle
{ "value": "jwt", "label": "JWT stateless" },
{ "value": "session", "label": "Server-side session" }
],
"required": true // optional (default false)
},
"text": { "required": true, "placeholder": "Justify" } // text ALWAYS present at runtime; required decided per-block
}
]
}
- 不包含
controls→ 报告段落;包含 → 问题。混合列表 → 混合表单。 controls.type:single(单选按钮)、multi(复选框)、toggle(布尔开关,不使用options)。controls.required和text.required相互独立——每个块可要求其中任意一项、两项或都不要求。id是 AI 分配的稳定键,用于映射对应答案。
完整规范(每个字段、默认值、验证规则)→ references/schema.md。可直接复制粘贴的示例规范 → references/examples.md。
精确调用
- 编写规范并保存到 JSON 文件。约定:
~/.toki/spec-<name>.json(使用spec-<name>.json文件名,备份会保存到~/.toki/result-<name>.json)。将规范保存在~/.toki/下,而非仓库中,可避免在你正在处理的仓库中留下任何文件。 - 运行(阻塞):
toki <specPath>。此命令会提供 UI、打开浏览器并等待。(在一个会话中首次运行时:先执行上面的 Phase 0 二进制检查。)- 标志:
--port <n>(默认值为 4747;端口占用时自动递增)、--timeout <min>(默认值为 1440,即 24h;可使用小数)、--no-open(打印 URL,但不打开浏览器)、--help。
- 标志:
- 解析 stdout。 stdout 仅包含 Result JSON——一个对象,不含横幅。所有进度行、等待 URL 和错误都会输出到 stderr。读取 stdout,使用
JSON.parse解析,并在同一轮中继续。
退出代码:
| Code | 含义 |
|---|---|
| 0 | 已成功提交——Result JSON 在 stdout 上 |
| 1 | 超时(在 --timeout 时间内未提交)或运行时错误——stdout 上没有可用内容 |
| 2 | 规范有误(文件无法读取或验证失败)——错误信息 [toki] invalid spec at <path>: … 输出到 stderr |
Result 的备份也会写入 ~/.toki/result-<name>.json,但对 AI 来说,stdout 中的副本具有权威性。
用户暂离协议
会话可能持续较长时间——默认 --timeout 为 24h(1440 min),可通过 --timeout <min> 调整。用户可能会暂时离开并让会话保持打开,因此非零退出代码不一定表示出错:
| 退出代码 | 含义 | AI 的处理方式 |
|---|---|---|
| 0 | 已提交——stdout 上有 Result JSON | 解析并在同一轮中继续 |
| 1 | 已超时,且未提交任何内容(或发生运行时错误) | 视为用户暂离,而非失败——见下文 |
| 2 | 规范有误(无法读取/验证失败) | 修正规范,然后重新运行 |
| 130 | Ctrl-C(SIGINT) | 用户已取消——询问他们接下来想做什么 |
退出代码为 1 时,不要直接报错或默默继续。应视为用户暂时离开了键盘:发送一条简短的待命消息,并询问是否要重新启动,例如:“我让 toki 保持等待,但还没有收到回复;我会继续待命——你说一声,我就重新启动。”准备好使用同一份规范重新运行 toki,用户一回来就能立即启动。
读取 Result
{
"submittedAt": "2026-05-29T12:34:56.000Z",
"blocks": [
{ "id": "q1", "controlAnswer": "jwt", "text": "Prefer JWT for scale", "quotes": ["token strategy"] }
],
"meta": { "answered": 5, "total": 8 }
}
对于每个 ResultBlock,根据区块的控件类型解码 controlAnswer:
single→string(所选选项的value),若未作答则为null。multi→string[](所选选项的value;若未选择则为[])。toggle→boolean。- 报告区块/无控件 →
null。
其他字段:
text——该区块中用户填写的自由文本(未编辑时为空字符串"")。quotes——string[],包含用户从该区块的content中选中的原文短语。这些短语能准确表明回复强调了哪些内容;解读text时应赋予它们较高权重。images——仅当用户向该区块(或表格行)粘贴了至少一张图片时才会出现。每个条目都是~/.toki/下的绝对文件路径,AI 可通过Read读取——绝不会以内嵌 base64 的形式出现。meta.answered——含有任意答案(选择了控件和/或填写了非空文本)的区块数量;meta.total——区块总数。
将每个 blocks[].id 与规范中分配的 id 对应起来,以便把每个答案关联到相应的决策/段落。
备注
- UI 界面文字为英文(仓库产物规则);区块的
content使用你编写时所用的语言。 - CLI 已解耦(仅使用 Bun 内置功能,无外部依赖),因此会作为独立的全局二进制文件发布——见
cli/README.md。