blurt
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseblurt 🐔 — show it, say it, get structured work back
blurt 🐔 — 展示、说出来,得到结构化工作成果
People think best out loud with their eyes on the screen. They jump between topics, correct themselves, point at
things. Your job: capture that with no friction, then do the tedious part (splitting, writing up, picking and
marking screenshots, finding the code, filing) with care. Optimise for the user's flow: never interrupt a
recording, ask few questions, make review fast.
Scripts live in next to this file; run them with (each
declares its deps; installs them on first use). Every script has . Always reply in the user's
language; write items in the language the user spoke.
scripts/uv run <skill-dir>/scripts/<name>.py ...uv--help人们盯着屏幕、边说边想时最容易理清思路。他们会跳到不同话题,纠正自己,指着屏幕上的内容。
你的任务是零摩擦地捕捉这些表达,再细致完成繁琐工作:拆分、撰写、挑选并标注截图、查找代码、归档。
优先适配用户的工作节奏:录制过程中绝不打断,尽量少提问,让审核快捷高效。
脚本位于本文件旁边的 ;使用 运行(每个脚本都会声明自己的依赖; 会在首次使用时自动安装)。每个脚本都支持 。始终使用用户的语言回复;条目也应使用用户说话时的语言撰写。
scripts/uv run <skill-dir>/scripts/<name>.py ...uv--help0. Setup (first run, or when something fails)
0. 设置(首次运行或执行失败时)
- → OS, RAM/GPU, ffmpeg, configured ASR, recommendations,
doctor.pylist.todo - Missing ffmpeg/uv: offer the install command; run it only after the user agrees.
- ASR: if none configured, pick from + the language the user speaks, tell the user in one line what and why (size, local vs cloud, cost), run its
asr_recommendations. Details:setup. Cloud keys are set by the user in their env — never ask them to paste keys in chat.reference/asr.md - — macOS: compiles the native recorder (Xcode Command Line Tools; else a Tk fallback) and installs the Blurt menu-bar app into ~/Applications. Windows: the Start-menu shortcut appears on first recording. Mention it in one line: "Blurt is also in your Applications — ⌥⇧R records from anywhere".
record.py build - → look at the returned
record.py testyourself. Wallpaper-only/black orframe⇒ Screen Recording permission missing;ok: false⇒ Microphone permission / wrong mic. On macOS the permission belongs to the app hosting you (Terminal, iTerm, VS Code, Claude, Codex…) and that app must be restarted after granting. macOS 15+ may show an "allow … to bypass the window picker" prompt — the user clicks Allow themselves.mic_silent: true - Optional project config : export target, owners/module map, column mapping, custom lenses in
.blurt/config.json. Suggest adding.blurt/lenses/to.blurt/sessions/..gitignore
- → 检查 OS、RAM/GPU、ffmpeg、已配置的 ASR,并给出建议和
doctor.py列表。todo - 缺少 ffmpeg/uv:提供安装命令;只有用户同意后才能运行。
- ASR:如果尚未配置,根据 和用户使用的语言进行选择,用一行说明所选方案及原因(大小、本地或云端、成本),然后运行其
asr_recommendations。详情见setup。Cloud keys 由用户在环境变量中设置——绝不能要求用户在聊天中粘贴 keys。reference/asr.md - — macOS:编译原生录制器(需要 Xcode Command Line Tools;否则使用 Tk fallback),并将 Blurt 菜单栏 app 安装到
record.py build。Windows:首次录制时会出现开始菜单快捷方式。用一行提醒用户:“Blurt 也位于你的‘应用程序’中——⌥⇧R 可从任意位置开始录制”。~/Applications - → 自行查看返回的
record.py test。如果画面只有壁纸或全黑,或显示frame,说明缺少 Screen Recording 权限;如果显示ok: false,说明缺少 Microphone 权限或选错了麦克风。在 macOS 上,权限归属于承载你的 app(Terminal、iTerm、VS Code、Claude、Codex……),授权后必须重启该 app。macOS 15+ 可能显示“允许……绕过窗口选择器”的提示——需要用户自行点击“允许”。mic_silent: true - 可选的项目配置 :导出目标、owners/module 映射、列映射,以及
.blurt/config.json中的自定义 lenses。建议将.blurt/lenses/添加到.blurt/sessions/。.gitignore
1. Record (or pick up a recording)
1. 录制(或获取已有录像)
From the chat: if the thing to look at is a local dev server/app in this repo, check it is running. Start
in the background ( to reuse the last area) and tell the user in a few lines
what happens:
record.py start--last-region- a dimmed overlay: drag to draw the area (or click a window, F = full screen) → 开始录制 / Enter. Only that area is recorded — tabs, bookmarks and other windows stay private;
- 3-2-1 countdown (click to skip), then a small floating bar: timer · mic level · ⏸ pause · ↺ restart/discard · 完成. ⌥⇧P pause/resume, ⌥⇧S finish (Windows: Alt+Shift). The bar is never in the recording;
- talk naturally, point with the mouse; hold ⌃ and drag to circle / underline what you mean (macOS; the ink
fades after 3 s; ✎ on the bar or ⌥⇧D keeps the pen on, Esc / ⌥⇧D / ✎ turns it off); click 完成 — no need to send another chat message.
The task ends with → continue with §2 right away (
DONE video=…, exit 2 → acknowledge and stop). From the chat you can alsoCANCELLED.record.py stop | pause | resume | restart
Waiting on a background step (here and in §5): if your harness wakes you when a background task finishes (Claude
Code), end your turn — you'll be notified. If it doesn't (Codex), a finished turn can't be resumed by the child
process: keep the turn open and wait on that same tool session with long polls (no busy loop); don't send a final
response while it runs.
Existing video (QuickTime, OBS, Loom, phone, a teammate's Blurt recording…): create
, copy it in as (with / if it came from
Blurt), continue with §2.
.blurt/sessions/<timestamp>/recording.<ext>events.jsonlmeta.jsonBlurt app recordings: the menu-bar app records into the current workspace — by
default, or when a project is bound. lists all of them with
/ flags. "Process my recordings" → do §2–§4 for each unprocessed one (fan out to subagents
if available), then one review per session (or merge into one session dir if the user wants a single list).
has — keep it on items when several people's recordings are combined.
~/Blurt/recordings/<ts>/<project>/.blurt/sessions/<ts>/record.py inboxprocessedreviewedmeta.jsonauthor从聊天发起:如果待处理对象是本 repo 中的本地 dev server/app,先检查它是否正在运行。在后台启动
(使用 可复用上次区域),并用几行文字说明接下来会发生什么:
record.py start--last-region- 出现变暗的 overlay:拖动绘制录制区域(或点击一个窗口,按 F 全屏)→ 开始录制 / Enter。只有该区域会被录制;标签页、书签和其他窗口均保持私密;
- 3-2-1 倒计时(点击可跳过),随后出现小型悬浮栏:计时器 · 麦克风音量 · ⏸ 暂停 · ↺ 重录/丢弃 · 完成。⌥⇧P 暂停/继续,⌥⇧S 完成(Windows:Alt+Shift)。悬浮栏不会出现在录像中;
- 自然地说话并用鼠标指向内容;按住 ⌃ 并拖动,即可圈出或下划出你所说的位置(macOS;笔迹会在 3 秒后淡出;点击悬浮栏上的 ✎ 或按 ⌥⇧D 可保持笔开启,Esc / ⌥⇧D / ✎ 可将其关闭);点击 完成——无需再发送聊天消息。
任务以 结束 → 立即继续执行 §2(
DONE video=…、退出码 2 → 确认后停止)。也可以在聊天中执行CANCELLED。record.py stop | pause | resume | restart
等待后台步骤时(此处及 §5):如果 harness 在后台任务完成时唤醒你(Claude Code),结束当前 turn——届时你会收到通知。如果不会(Codex),已结束的 turn 无法由子进程恢复:保持当前 turn 打开,在同一个 tool session 上使用长轮询(long polls)等待(不要 busy loop);任务运行期间不要发送最终回复。
已有视频(QuickTime、OBS、Loom、手机、队友的 Blurt recording……):创建
,将视频复制为 (如果来自 Blurt,同时复制 / ),然后继续执行 §2。
.blurt/sessions/<timestamp>/recording.<ext>events.jsonlmeta.json**Blurt app 录像:**菜单栏 app 默认将录像录到当前 workspace 的 ;绑定项目后,则录到 。 会列出所有录像及其 / 标记。“处理我的录像” → 对每个未处理的录像执行 §2–§4(如果 harness 支持,可并行分派给 subagents),随后每个 session 审核一次;如果用户希望得到一份统一列表,也可以合并到一个 session dir。 中包含 ——合并多人录像时,应将 author 保留在对应 items 上。
~/Blurt/recordings/<ts>/<project>/.blurt/sessions/<ts>/record.py inboxprocessedreviewedmeta.jsonauthor2. Transcribe
2. 转录
transcribe.py run <session>/recording.mp4transcript.jsontranscript.txt[mm:ss.s-mm:ss.s] textrecord.py start --system-audio(system)speaker: "system"--promptframes.py scan <video>frames.py marks <video>warningreference/asr.mdtranscribe.py run <session>/recording.mp4transcript.jsontranscript.txt[mm:ss.s-mm:ss.s] textrecord.py start --system-audio(system)speaker: "system"--promptframes.py scan <video>frames.py marks <video>warningreference/asr.md3. Understand → items
3. 理解 → 条目
Read the whole transcript first, glance at a few frames, then write
(schema: ). Decide per item what it is — the recording decides, not a mode switch:
<session>/items.jsonreference/schema.md| kind | when | lens |
|---|---|---|
| something in the product to fix or polish | |
| something to build / change / borrow ("这个网站的这里好") | |
| an observation / finding / fact worth keeping | |
| an action item that isn't a product issue | |
| custom | a lens in | that file |
Principles — judgement, not rules:
- A pen mark is the user saying "this, exactly": it anchors an item's time and subject. What they circled outranks your reading of a vague sentence — but a mark is not an item by itself, and items without marks are normal.
- One item = one thing. People jump around, revisit, correct themselves ("不对,是…"), or say two things in one sentence: merge revisits, drop retracted remarks, split compounds. Pure narration is not an item.
- Fix ASR errors from context (repo vocabulary, what's on screen). Keep close to what was said.
quote - Don't invent. When unsure, write your best guess, set , add a short
confidence: "low"entry.questions - Read URLs / product names off the frames into .
source - (issues, inside a repo): grep the visible text / route / component; list the likely
code_refss.path:line - Give the session a . For idea-heavy or exploratory recordings write a
title(markdown): themes, the strongest ideas, how they connect, suggested next step — it becomes the review page's Overview.digest
先完整通读 transcript,再浏览几帧,然后写入
(schema:)。逐条判断它是什么——由 recording 决定,而不是切换模式:
<session>/items.jsonreference/schema.md| kind | 何时使用 | lens |
|---|---|---|
| 产品中需要修复或打磨的某项内容 | |
| 需要构建、修改或借鉴的某项内容(“这个网站的这里好”) | |
| 值得保留的观察、发现或事实 | |
| 不属于产品 issue 的行动项 | |
| | 该文件 |
原则——依靠判断,而不是机械规则:
- 笔迹标记意味着用户在说“就是这个”:它会锚定条目的时间和主题。圈画内容优先于你对模糊语句的解读——但标记本身并不自动构成一个条目,没有标记的条目也很正常。
- 一个 item 只对应一件事。人们会跳来跳去、反复讨论、纠正自己(“不对,是……”),或在一句话里说出两件事:合并回访内容,删除已撤回的表述,拆分复合内容。单纯叙述不是条目。
- 根据上下文修正 ASR 错误(repo 词汇、屏幕上的内容)。让 尽量贴近原话。
quote - 不要臆造。不确定时,写下最佳推测,设置 ,并添加一条简短的
confidence: "low"。questions - 从 frames 中读取 URL / 产品名称并写入 。
source - (repo 内的 issues):grep 可见文本、route 或 component;列出可能的
code_refs。path:line - 为 session 设置 。对于包含大量 ideas 或探索内容的录像,编写
title(markdown):包括主题、最有价值的 ideas、它们之间的联系以及建议的下一步——它将成为审核页的 Overview。digest
4. Evidence: frames & clips
4. 证据:frames 与 clips
Pick 1–3 frames per item that show the point (the bug itself, the part of the page that inspired the idea):
- → ~6 diverse settled candidates with timestamps in one image;
frames.py sheet <video> --from S --to E -o <session>/sheets/<id>.jpgfor specific moments ("这里 / this / look"). Speech often trails the action.--at t1 t2 … - The user drew on it ()? Their ink is in the video:
marksand the frame is already annotated — add no box.frames.py grab --at <frame_t>for a zoomed second frame;--crop strokeon a frame where the ink is gone.--box stroke - Otherwise, marking the spot — never estimate coordinates from a thumbnail or contact sheet:
- → labelled 0–1 grid plus the recorded cursor and nearby clicks (events.jsonl — exact). Read box edges off the grid (
frames.py grid <video> --at T -o <session>/sheets/<id>-grid.jpgzooms, labels stay full-frame).--crop - ;
frames.py grab <video> --at T -o <session>/frames/<id>-1.jpg --box x,y,w,hwhen the user pointed at / clicked it. Tiny detail → second frame with--ring cursor|click.--crop - Look at every annotated frame before using it. Box not on the point → fix and re-grab.
- Animations / flows / timing: (< 20 MB).
frames.py clip --from --to -o <session>/clips/<id>.mp4 - Many items (> ~12)? Fan out frame work to subagents in batches if your harness has them.
每个条目挑选 1–3 个能够展示要点的 frames(bug 本身,或启发 idea 的页面部分):
- → 在一张图片中提供约 6 个内容多样且画面稳定的候选项,并附带时间戳;使用
frames.py sheet <video> --from S --to E -o <session>/sheets/<id>.jpg可指定特定时刻(“这里 / this / look”)。语音往往滞后于操作。--at t1 t2 … - 用户是否在画面上做了笔迹标注()?笔迹已经录入视频:使用
marks得到的 frame 已带标注——不要再添加方框。frames.py grab --at <frame_t>可生成第二张放大 frame;笔迹消失后的 frame 使用--crop stroke。--box stroke - 否则需要标注目标位置——绝不能根据缩略图或 contact sheet 估算坐标:
- → 生成带 0–1 网格坐标的标注图,同时显示录制时的光标及附近点击(events.jsonl——坐标精确)。根据 grid 读取方框边缘(
frames.py grid <video> --at T -o <session>/sheets/<id>-grid.jpg可放大,同时保留完整画面上的坐标标签)。--crop - ;用户指向或点击的位置使用
frames.py grab <video> --at T -o <session>/frames/<id>-1.jpg --box x,y,w,h。如果目标很小,再使用--ring cursor|click生成第二张 frame。--crop - **使用每一张标注 frame 前都要亲自查看。**如果方框没有对准要点 → 修正并重新抓取。
- 涉及动画、流程或时序的问题:(小于 20 MB)。
frames.py clip --from --to -o <session>/clips/<id>.mp4 - 条目很多(> ~12)?如果 harness 支持 subagents,可按批次并行处理 frame 工作。
5. Review with the user
5. 与用户审核
Always open the review page — the frames are the point. Run in the background (opens the
browser, exits when the user finishes). In the same message:
review.py <session>- ≤ 5 items: the full numbered list (kind · title · owner/module, plus ); more: a short summary (counts by kind, the headline items, open questions);
questions - two lines on the page: one item at a time — A keep · X drop · J/K next/prev · Z undo · ? keys;
fields editable in place; G list view; V overview (when there's a digest); "完成审核" hands it back.
The user may answer in chat or on the page. Wait as in §1 until the review summary prints, then reload (dropped items have
items.json, answers are instatus: "deleted", merged items are gone on purpose and listed in the target'sanswer) and continue with §6. If they reply in chat instead, apply it yourself and close the page (merged_from).pkill -f "review.py <session>"
Unattended runs (started by the Blurt app via / — env — or any other
non-interactive mode): don't ask anything; do §2–§4 and write , then finish with a 2–3 sentence summary.
With don't start the review page — the app opens it when you exit; otherwise start it detached
(). Never export to external systems unattended.
claude -pcodex execBLURT_APP=1items.jsonBLURT_APP=1nohup uv run …/review.py <session> >/dev/null 2>&1 &始终打开审核页——frames 才是关键。在后台运行 (打开浏览器,并在用户完成审核后退出)。在同一条消息中:
review.py <session>- 不超过 5 个条目:提供完整编号列表(kind · title · owner/module,以及 );超过 5 个:提供简短摘要(按 kind 统计、重点条目、待解决的问题);
questions - 用两行说明页面操作:每次显示一个条目——A 保留 · X 丢弃 · J/K 下一个/上一个 · Z 撤销 · ? 查看按键;
字段可就地编辑;G 切换列表视图;V 查看 Overview(存在 digest 时);“完成审核”后交回结果。
用户可以在聊天中或页面上回答。按照 §1 的方式等待,直到审核摘要输出,然后重新加载 (丢弃的条目会显示
items.json,回答保存在status: "deleted"中,被合并的条目会按预期消失,并列在目标条目的answer中),然后继续执行 §6。如果用户改为在聊天中回复,则自行应用其修改并关闭页面(merged_from)。pkill -f "review.py <session>"
无人值守运行(由 Blurt app 通过 / 启动——环境变量 ——或任何其他非交互模式):不要询问任何问题;执行 §2–§4 并写入 ,然后用 2–3 句话总结结束。
当 时,不要启动审核页——你退出后 app 会自动打开;否则应以后台分离方式启动()。无人值守时绝不能向外部系统导出。
claude -pcodex execBLURT_APP=1items.jsonBLURT_APP=1nohup uv run …/review.py <session> >/dev/null 2>&1 &6. Export / act
6. 导出 / 执行
Ask once where things go (remember in → ). Typical: issues → the team's bug table;
ideas → an ideas board / doc; notes → Markdown; tasks → the user's todo tool.
.blurt/config.jsonexport- Feishu/Lark Bitable → (lark-cli if installed, else app credentials; default columns per kind, creates missing ones, uploads frames + clips, resumable). No table yet →
feishu.py export <session> "<table url>" [--kind issue|idea|…]. Other columns →feishu.py create "<name>"thenfeishu.py fields. Details:--map.reference/export-feishu.md - Markdown + CSV → (all kinds; always a good local record).
export_local.py <session> - GitHub Issues / Linear / Jira / Notion / Obsidian / anything else → ; use the CLI or MCP tool the user has; map fields by meaning.
reference/export-other.md - A document rather than a list ("整理成需求文档和设计文档", a brief, a comparison — typically after walking through
reference sites or a competitor, often across several recordings) → . Confirm destination and count before creating anything remotely; report links afterwards. Then offer the natural next step — for issues "want me to start fixing these?" (you have
reference/docs.md), for ideas "want a quick prototype / spec of the top one?".code_refs
只需询问一次内容要导出到哪里(记住 → 中的设置)。典型映射:issues → 团队的 bug table;ideas → ideas board 或文档;notes → Markdown;tasks → 用户的 todo 工具。
.blurt/config.jsonexport- Feishu/Lark Bitable → (如果已安装 lark-cli,则使用 lark-cli,否则使用 app credentials;每种 kind 都有默认列,可创建缺失的列,并上传 frames 与 clips,支持断点续传)。 还没有 table →
feishu.py export <session> "<table url>" [--kind issue|idea|…]。需要其他列 →feishu.py create "<name>",然后使用feishu.py fields。 详情见--map。reference/export-feishu.md - Markdown + CSV → (支持所有 kinds;始终适合作为本地记录)。
export_local.py <session> - GitHub Issues / Linear / Jira / Notion / Obsidian / 其他任何系统 → ;使用现有 CLI 或 MCP tool;按含义映射字段。
reference/export-other.md - 如果用户需要的是文档而不是列表(“整理成需求文档和设计文档”、brief、comparison——通常发生在浏览 reference sites 或 competitor 之后,而且经常横跨多个 recordings)→ 。 在远程创建任何内容前,确认目标位置和条目数量;完成后报告链接。随后提供自然的下一步——对于 issues,询问“需要我开始修复这些问题吗?”(你已有
reference/docs.md);对于 ideas,询问“需要为其中最好的一个快速制作 prototype / spec 吗?”。code_refs