mcpField
M
mkd

mkd

github.com/upex-galaxyAgent 工作流048 次安装4 周前更新
代码仓库

关于 mkd

MKD 是一个本地命令行工具,可将决策、问题、报告和表格整理成逐屏作答的浏览器卡片组。它面向需要结构化输入的 AI 对话,并将回答以 JSON 形式返回,作为后续执行依据。

主要功能

  1. 01支持四种卡片项目类型
  2. 02决策选项必须附书面理由
  3. 03支持复制粘贴和等待式回答
  4. 04支持 Orca 与 Claude Code artifact 流程
  5. 05卡片组和结果保存在 ~/.mkd/

适用场景

  1. 01收集多个决策的权衡意见
  2. 02征集对报告各部分的反馈
  3. 03逐行审阅表格并给出判断
  4. 04向 AI 对话返回结构化答案

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/upex-galaxy/agentic-user-skills --skill mkd

安装后在 Claude Code 中输入/mkd确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

cli/
assets.d.ts
index.ts
markdown.ts
orca.test.ts
orca.ts
README.md
render.test.ts
render.ts
schema.ts
server.ts
cli/ui/
app.css
app.js
references/
examples.md
schema.md
setup.md

详细介绍

MKD(mkd)——制定决策

MKD 是一个本地决策卡组 CLI,AI 会在对话过程中调用它。它会生成一个浏览器页面,让用户每屏处理一个事项(类似 Slack Catch-Up):包含附有理由的决策选项、带控件的问题、供用户反馈的报告章节,以及可作答的表格。默认流程是非阻塞式复制粘贴:CLI 打开页面后即退出;用户可随时作答,再将结果 JSON 粘贴到聊天中。该 JSON 就是执行约定——AI 会严格按其中内容执行。

此技能无需安装:没有编译后的二进制文件,也不会向 PATH 添加任何内容。AI 使用 Bun 在技能目录中运行 CLI。所有输出(生成的卡组、结果、图片)都写入 ~/.mkd/ 下,而非当前工作目录,因此在任何代码库中运行都不会留下任何痕迹。

运行(无需安装)

bun "<skill-dir>/cli/index.ts" <specPath> [--wait | --copy] [--no-open] [--port <n>] [--timeout <min>]
bun "<skill-dir>/cli/index.ts" <specPath> --artifact --title-prefix <session-name>   # Claude Code only

<skill-dir> 是此技能的安装目录:

  • 项目级:<repo>/.claude/skills/mkd
  • 用户级:~/.claude/skills/mkd

Bun 可直接运行 TypeScript;冷启动耗时可以忽略。如果未安装 Bun,请告知用户安装(curl -fsSL https://bun.sh/install | bash)——不要改用 Node。

何时使用 MKD,而非 AskUserQuestion 或直接在文字中提问

情况使用
选择 1~2 个选项、单个是/否问题,或 ≤3 个简单决策AskUserQuestion
>3 个决策点,或需要结合背景和书面权衡信息的决策MKD
用户需要逐项反馈的长篇多章节报告/计划MKD(report 项)
需要逐行评判表格数据MKD(table 项)
回复必须以确切短语为依据MKD(高亮并引用)
非交互场景 / CI / 浏览器前没有用户两者都不用——输出纯文本

卡组模型

规范由一组事项组成;每个事项占一个屏幕。共有四种类型:

类型屏幕内容捕获的回答
decision问题说明(使用通俗的 PM 语言)+ 可折叠的背景信息气泡 + 附有书面理由的选项 + 可选的自定义选项 + 备注chosen 键(或 "CUSTOM" + customText)、wasRecommended、note
questionMarkdown 内容 + single/multi/toggle 控件 + 自由文本controlAnswer、text、quotes
report供用户反馈的报告章节text、quotes
table可作答的表格,每行对应一个答案(弹出式控件 + 文本)每行的 rows[] 包含 controlAnswer/text/quotes,另有事项级别的 note

卡组界面始终包含:介绍屏幕(标题 + Markdown + 统计卡片)、可导航的进度栏、← → 方向键、每个事项均可选择暂时跳过(跳过 = 以后再决定,不是拒绝)、摘要屏幕、页脚实时统计(已回答 / 采纳推荐 / 已更改 / 自定义 / 已跳过)、浅色/深色主题、localStorage 持久化(关闭标签页也不会丢失内容)。

硬性规则——选项必须附有理由(这是此工具的核心)

编写 decision 事项时:

  1. 每个选项都必须附有书面 justification:说明它能带来什么(价值)以及需要付出什么代价。校验器会拒绝没有理由的选项(退出码 2)——不要试图规避,写明理由即可。
  2. 最多只能有一个选项标记为 recommended,且其理由必须明确说明为何推荐此选项(例如:“推荐,因为……”)。
  3. problem 必须使用通俗语言(PM 口吻)撰写,让不了解全部技术背景的人也能看懂;术语和内部代号应放在 context 气泡中,并解释当前的工作方式。
  4. 用户应了解的每项真实权衡都必须写明。没有解释的选项列表,正是此工具要消除的问题。

规范结构简述

{
  "session": "audit-skills-alignment",   // required — result echo + persistence key
  "source": ".session/.../audit.md",     // optional pointer to the source artifact
  "title": "Catch-Up: audit decisions",  // required
  "intro": {                              // optional intro screen
    "headline": "8 decisions await you",
    "body": "Markdown, PM voice",
    "stats": [{ "n": "115", "label": "verified findings" }]
  },
  "items": [
    {
      "id": "D1", "type": "decision", "title": "…",
      "severity": "high",                // optional: high | medium | low (chip)
      "scope": "test-documentation",     // optional (chip)
      "problem": "Plain-language markdown problem statement",
      "context": [{ "title": "How does X work today?", "body": "markdown" }],
      "options": [
        { "key": "A", "label": "…", "justification": "Value + cost. **Recommended** because …", "recommended": true },
        { "key": "B", "label": "…", "justification": "Value + cost." }
      ],
      "allowCustom": true                // default true
    },
    { "id": "Q1", "type": "question", "title": "…", "content": "markdown",
      "controls": { "type": "single", "required": true, "options": [{ "value": "keep", "label": "Keep" }] },
      "text": { "placeholder": "Why?" } },
    { "id": "R1", "type": "report", "title": "…", "content": "markdown section" },
    { "id": "T1", "type": "table", "title": "…", "content": "optional intro",
      "table": { "columns": ["Test", "Rate"], "rows": [{ "id": "r1", "cells": ["a", "b"] }],
                 "rowControls": { "type": "single", "options": [ … ] } } }
  ]
}

完整约定(所有字段、默认值、校验规则)→ references/schema.md。可直接复制粘贴的规范示例 → references/examples.md。

按运行环境选择流程

根据你运行所用的环境选择流程。Artifact 模式需要使用 Artifact、ArtifactData 和 ArtifactComments 工具,只有 Claude Code 提供这些工具(而且仅限已登录 claude.ai 的会话)。CLI 无法调用这些工具,因此不会自行选择 Artifact 模式;你可以通过 --artifact 选择该模式,并自行发布页面。

运行环境流程操作方式
工具列表中包含 Artifact 工具的 Claude CodeArtifact 模式--artifact --title-prefix <session-name>,然后发布并监视(步骤见下文)
不含 Artifact 工具的 Claude Code(未登录 claude.ai:API key、Bedrock、Vertex),或子 Agent/打印会话(无法保持监视)其他运行环境使用的流程如下所述
OpenCode、Cursor、Codex 或其他环境在 Orca 内使用 Orca 标签页,否则使用复制模式;如需在同一轮获得回答,使用 --wait参见“运行哪种流程:使用 Orca 还是不使用”

Claude Code 会在其运行的 shell 中设置 CLAUDECODE=1。这能确认运行环境,但无法证明此会话拥有 Artifact 工具,因此 CLI 检测到它时只会在 stderr 中打印一行提示,并继续使用常规默认设置。请直接检查你自己的工具列表。

精确调用方式 — Claude Code(Artifact 模式)

用户在 claude.ai 的 Artifact 中作答。发送给 Claude 会将 Result JSON 保存到 Artifact 的数据库中,并发布一条发给 Claude 的评论,以唤醒此会话。不会在 localhost 上运行任何内容,也无需复制。

  1. 将规范写入 ~/.mkd/spec-<name>.json,然后运行: bun "<skill-dir>/cli/index.ts" ~/.mkd/spec-<name>.json --artifact --title-prefix <session-name>。 会话名称是 ListAgents 的第一行(“This session is …”)或终端标题。CLI 会验证规范,写入 ~/.mkd/artifact-<name>.html(一个页面片段:首项为 <title>,不含 doctype/html/head/body),仅将该路径打印到 stdout,不打开任何内容,并以 0 退出。stderr 会显示答案将写入的数据库文档。与往常一样,退出码 2 表示规范无效。
  2. 使用 Artifact 工具发布该文件:file_path = 打印出的路径,设置 icon(例如 checklist)、一行 description,以及 capabilities: {db: {}, comments: {}}。将链接提供给用户。
  3. 确认监视已启用:调用 ArtifactComments,设置 action: "watch",不提供 url,即可列出此会话的监视项。Artifact 对应的行必须显示自动回复已启用;若没有显示,则使用其 url 调用 watch。只有启用自动回复的监视项才能让“发送”操作唤醒此会话。之后结束本轮或继续工作;不要轮询。
  4. 唤醒后(用户在该 Artifact 中发送了发给 Claude 的评论):调用 ArtifactData,设置 action: "get"、collection: "results" 和 doc_id:即规范中的 session(stderr 会打印确切 ID;数据库路径不接受的字符会替换为 -)。result 字段是 Result JSON 字符串:解析它,并像复制模式中一样将其视为执行约定。回复评论线程,说明你将采取的操作,然后解决该评论(先调用 ArtifactComments 的 reply,再调用 resolve)。
  5. 修改问卷:编辑规范,重新运行相同命令,并再次发布到相同的 file_path(也可以传入来自其他对话的 Artifact url):URL 会保持不变,已保存的答案也会保留,因为浏览器存储属于该 Artifact。

如果页面显示“此视图中无法发送”(查看者没有 db 授权,例如仅有查看权限),用户仍可点击复制 JSON,并将其粘贴到聊天中。如果答案已保存,但通知失败(“已保存,但未通知 Claude”),用户可以在聊天中告知你,然后按照步骤 4 读取数据库文档。Artifact 模式下禁用粘贴图片(没有用于存储图片数据的服务器)。

运行 Orca 流程还是非 Orca 流程

CLI 会先检查 Orca,然后才打开任何内容。当设置了 ORCA_TERMINAL_HANDLE(进程在 Orca 管理的终端中运行),或者 orca status --json 报告运行时可访问时,Orca 即视为已运行。可执行文件的解析方式与 Orca 自带的 orca-cli skill 相同:先检查 ORCA_CLI_COMMAND,然后检查 Orca 开发版检出目录中的 orca-dev,再检查非受管理终端中的 Linux 系统上的 orca-ide(此处单独使用 orca 通常会启动 GNOME 屏幕阅读器),最后检查 orca。检查失败时视为“没有 Orca”,且不输出任何内容。

环境标志执行结果
没有 Orca无复制模式:渲染内容、打开系统浏览器,然后以状态码 0 退出。行为不变。
没有 Orca--wait启动服务、打开系统浏览器,并阻塞等待提交
有 Orca无Orca 流程:启动服务,打开一个绑定到当前工作树的标签页,并阻塞等待用户按下 Send to Claude;结果 JSON 输出到 stdout
有 Orca--copy复制模式,使用系统浏览器,并以状态码 0 退出(旧流程)
任意--no-open与上述模式相同,但不打开任何内容;路径或 URL 输出到 stderr

标签页通过 --worktree path:<git toplevel of the cwd> 绑定,因此请从用户正在使用的检出目录中运行 CLI。执行 orca tab create 后,CLI 会读取 orca tab list,并检查标签页是否存在且其 loadError 是否为 null。如果无法创建标签页或页面加载失败,CLI 会关闭自己创建的任何标签页,改为打开系统浏览器,并在 stderr 中说明情况。运行结束时(提交、超时、Ctrl-C 或 SIGTERM),CLI 会关闭已打开的标签页;如果关闭失败,stderr 会提示该标签页现在指向一个已停止的服务器。

精确调用方式——在 Orca 中(默认)

CLI 会一直阻塞,直到用户提交,因此绝不要在前台运行它:前台调用会让 Agent 的轮次被占用,最长可达 24 小时。

  1. 将规格写入 ~/.mkd/spec-<name>.json。
  2. 在后台运行,工作目录设为用户的检出目录:
    • Claude Code:使用 Bash 工具,并设置 run_in_background: true,运行 bun "<skill-dir>/cli/index.ts" ~/.mkd/spec-<name>.json。进程退出时,运行环境会通知你;届时读取其标准输出。此行为在 Orca 1.4.190 上测得。
    • OpenCode / Codex / Cursor(未经验证:未在任何平台测量):使用 shell 将进程设为分离模式启动,输出写入 ~/.mkd/:nohup bun "<skill-dir>/cli/index.ts" ~/.mkd/spec-<name>.json > ~/.mkd/stdout-<name>.json 2> ~/.mkd/stderr-<name>.log &。重定向会截断日志,因此一旦 ~/.mkd/stderr-<name>.log 中出现 result written to,就表示本次运行的提交已完成:读取 ~/.mkd/result-<name>.json(与标准输出中的 Result 相同)。如果运行环境无法让后台进程保持运行,请传入 --copy 并使用下面的复制模式步骤。
  3. 告知用户:卡片组已在此终端旁边的标签页中打开,点击 Send to Claude 会直接返回答案,无需复制。然后结束轮次或继续工作。
  4. 进程退出后,根据退出码采取相应操作(参见 --wait 下方的表格)。退出码为 0 表示标准输出中包含 Result JSON:将其视为执行约定,与复制模式完全相同。

固定端口,答案持久保存。 每个卡片组都会在 4747-4946 范围内获得一个专属端口,该端口根据 spec-<name>.json 中的 <name> 计算(若没有,则根据 session 计算)。如果使用同一规格文件重新打开尚未完成的卡片组,它会使用相同的源,因此已保存的答案会恢复。如果该端口正忙,CLI 会绑定下一个空闲端口,并在标准错误中提示:原端口上保存的答案不会显示。--port <n> 可覆盖计算出的端口。

同一时间只保留一份卡片组副本。 浏览器存储按源和浏览器引擎分别隔离:同一卡片组在系统浏览器与 Orca 标签页中,或以 file:// 页面和通过回环地址访问时,会分别保存两套答案,且绝不会合并。CLI 会记住上次打开每个卡片组的位置(~/.mkd/opened-<name>.json),并在本次运行于其他位置打开时于标准错误中发出警告;看到该警告时,请告知用户当前使用的是哪份副本。如果先前存在 ~/.mkd/result-<name>.json 备份,CLI 也会提示(下次提交会覆盖该文件)。

精确调用方式——默认在 Orca 外部(复制模式,非阻塞)

  1. 将规格写入 ~/.mkd/spec-<name>.json(此文件名会使页面生成在 ~/.mkd/deck-<name>.html)。将其保存在 ~/.mkd/ 下可保持仓库整洁。
  2. 运行: bun "<skill-dir>/cli/index.ts" ~/.mkd/spec-<name>.json。CLI 会验证并渲染独立页面、打开浏览器,然后立即以退出码 0 结束。标准输出不会有任何内容。
  3. 告知用户:卡片组已在其浏览器中打开,点击页脚的 Copy JSON 并将内容粘贴到聊天中,即可返回答案。然后继续其他工作或结束轮次——不要阻塞或轮询。
  4. 收到粘贴的 JSON 后,解析它并将其视为执行约定:status: "skipped" 的项目表示“稍后再决定”(之后再次询问,绝不要擅自视为拒绝);chosen: "CUSTOM" 表示按 customText 中的内容执行(如有不合理之处,则进行询问);务必阅读每个项目的 note。

--wait(阻塞式,同一轮回答)

在 Orca 之外,仅当 AI 确实需要在同一轮中获得答案才能继续时才使用。在 Orca 中,这已经是默认流程。

  • bun "<skill-dir>/cli/index.ts" <specPath> --wait 会通过 loopback 提供问卷页面(--port,默认值:问卷页面的稳定端口,范围为 4747-4946,自动递增),并通过每次运行独有的 x-mkd-token 提交门控进行保护;它会等待浏览器提交(--timeout <min>,默认值为 1440 = 24h),然后将 Result JSON 输出到 stdout(stdout 上的唯一内容;横幅和错误信息会输出到 stderr),并将备份写入 ~/.mkd/result-<name>.json。
  • 粘贴图像(剪贴板 → 附件)仅在 wait 模式下有效(--wait 或 Orca 流程):images 中的条目会以 ~/.mkd/ 下的绝对文件路径形式传入,AI 可以使用 Read 读取。复制模式会禁用粘贴(没有服务来持久化字节数据)。

退出码和缺席处理协议(适用于 --wait 和 Orca 流程):

退出码含义AI 的处理方式
0已提交 — stdout 上有 Result JSON解析并在同一轮中继续
1超时且未提交(或运行时错误)用户暂时不在,不是错误 — 发送待命说明,并提出重新启动
2规格无效(无法读取 / 验证失败)修复报告路径下的规格,然后重新运行
130Ctrl-C用户已取消 — 询问他们接下来想做什么
143SIGTERM(运行框架或其他人终止了后台进程)使用相同规格重新启动;稳定端口会恢复已保存的答案

读取 Result

{
  "session": "audit-skills-alignment",
  "source": ".session/.../audit.md",
  "submittedAt": "2026-08-21T…",
  "stats": { "total": 8, "answered": 6, "skipped": 1, "recFollowed": 4, "overridden": 1, "custom": 1 },
  "items": [
    { "id": "D1", "type": "decision", "title": "…", "status": "answered",
      "chosen": "A", "chosenLabel": "…", "wasRecommended": true, "customText": "", "note": "…" },
    { "id": "Q1", "type": "question", "status": "answered", "controlAnswer": "keep", "text": "…", "quotes": ["…"] },
    { "id": "R1", "type": "report", "status": "skipped", "controlAnswer": null, "text": "", "quotes": [] },
    { "id": "T1", "type": "table", "status": "answered", "note": "", "quotes": [],
      "rows": [{ "id": "r1", "controlAnswer": "fix", "text": "", "quotes": [] }] }
  ]
}
  • Artifact 模式:相同的对象以 JSON 字符串形式存储在 results/<session> 的 result 字段中(与 session 和 submittedAt 并列)。与复制模式一样,它由页面生成,不会由服务重新调整格式。
  • controlAnswer 会根据控件类型解码:single → string|null,multi → string[],toggle → boolean。
  • quotes 是用户从该条目的内容(或该行的单元格)中高亮选取的原文短语 — 解读 text 时应考虑这些短语。
  • 将 items[].id(以及 rows[].id)与您编写的 ID 对应起来,为每个答案提供依据。

备注

  • UI 界面文字为英文(仓库工件规则);title/problem/content/说明文字可使用任意语言 — 请使用用户的语言撰写。
  • 页面会从 Google Fonts 加载显示字体,并提供完整的系统字体回退;离线时也能正常降级。
  • CLI 已解耦(仅使用 Bun 内置功能,不依赖任何外部依赖)— 参见 cli/README.md。

评论

支持 Markdown