review
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTailr — the review loop
Tailr — 评审循环
Tailr lets the person you are working with mark up their running dev server in
the browser — click an element, say what is wrong — and hand you every mark at
once as a batch. You apply the batch and report each mark as it lands.
The rules below are the whole protocol. They are the same rules
writes into a project's / ; this plugin carries them
instead, so nothing in the user's repository has to be edited.
<!-- tailr:start -->tailr initAGENTS.mdCLAUDE.mdTailr 允许你的协作对象在浏览器中对运行中的开发服务器进行标记——点击元素、说明问题——并将所有标记一次性批量提交给你。你需要批量应用这些标记,并在每个标记落地时同步反馈。
以下规则是完整的协议。这些规则与 写入项目 / 中的规则完全一致;本插件直接内置了这些规则,因此无需修改用户代码仓库中的任何内容。
<!-- tailr:start -->tailr initAGENTS.mdCLAUDE.mdTailr — visual markup from the reviewer
Tailr — 来自评审者的视觉标记
The reviewer marks up the running app in the browser and hands you the changes
as one batch. A session is up when exists; if it doesn't,
start one as a long-running background process — it must stay up, so don't block
your turn waiting on it:
.tailr/session.jsonnpx tailr --target http://localhost:<dev server port>It prints a review URL (usually http://localhost:4100). Tell the reviewer to use
that URL, not the original port. Tailr proxies the app and injects its overlay;
the source is not modified.
The loop is → → per mark → or .
waitpullprogressdonefail| Command | MCP tool | |
|---|---|---|
| | is a batch waiting? exit 0 yes · 3 session up, nothing waiting · 2 no session |
| | block until Send is pressed; exit 0 a batch is waiting · 3 timed out, start it again · 2 session ended |
| | lease the batch, printed as JSON |
| | name the versions you built for one mark |
| | report the continuous parameter you wired for a slider mark |
| | report one mark as applied |
| | the run finished |
| | it returned incomplete |
| | their settings — |
Each mark carries a ("01"), a , the it was made on, a
best-effort source , a CSS , the element's text, and the
reviewer's .
reftyperouteaddressselectorcomment- — change that element as described
comment - — delete that element
remove - — carries
text/before; change the text toafterafter - — carries page
point/xinstead of an element. The reviewer marked a place, not a thing: they may want something new there, or may just be noting the spot. Their comment says which.y - — the reviewer picked between versions you built, or kept a value on a slider you built. See below.
choice
评审者在浏览器中对运行中的应用进行标记,并将所有变更作为一个批量提交给你。当 存在时,表示会话已启动;如果不存在,需要将其作为长期运行的后台进程启动——会话必须保持运行,因此不要阻塞你的处理流程来等待它:
.tailr/session.jsonnpx tailr --target http://localhost:<dev server port>它会输出一个评审URL(通常是 http://localhost:4100)。告知评审者使用该URL,而非原始端口。Tailr 会代理应用并注入其覆盖层;不会修改源代码。
循环流程为 → → 每个标记执行 → 或 。
waitpullprogressdonefail| Command | MCP tool | |
|---|---|---|
| | 是否有批量任务等待处理?退出码 0 表示有 · 3 表示会话运行中,无等待任务 · 2 表示无会话 |
| | 阻塞直到按下发送按钮;退出码 0 表示有批量任务等待 · 3 表示超时,需重新启动 · 2 表示会话已结束 |
| | 获取批量任务的租约,以JSON格式输出 |
| | 为单个标记构建的版本命名 |
| | 上报你为滑块标记配置的连续参数 |
| | 上报单个标记已应用 |
| | 运行完成 |
| | 运行未完成(失败) |
| | 用户设置—— |
每个标记包含 (如"01")、、标记所在的 、尽力匹配的源 、CSS 、元素文本以及评审者的 。
reftyperouteaddressselectorcomment- — 按照描述修改对应元素
comment - — 删除对应元素
remove - — 包含
text/before字段;将文本修改为after的内容after - — 包含页面
point/x坐标而非元素。评审者标记的是一个位置而非某个元素:他们可能想在那里添加新内容,或者只是标注该位置。具体意图见其评论。y - — 评审者在你构建的版本中做出了选择,或确定了你构建的滑块的数值。详见下文。
choice
Versions
版本
A or mark can carry . That asks for three
different answers to the same comment, all built at once, so the reviewer can
compare them on the running page and keep one.
commentpoint"variations": 3Build every version into the source together, each guarded on the switch Tailr
sets for that mark: the attribute on , whose
value is the version number.
data-tailr-var-<ref><html>/* mark 03, version 2 */
[data-tailr-var-03="2"] .cart-total { font-size: 24px; border-radius: 14px }Version 1 must also be what renders when the attribute is absent, so the page is
never broken for anyone who isn't looking through Tailr. Anything that has to
re-render rather than restyle reads
and listens for the event on ; its carries
.
document.documentElement.dataset.tailrVar03tailr:variantdocumentdetail{ ref, variant, label }Then name them, in order, before you report that mark applied:
npx tailr variants 03 "Softer edges" "Full width" "Two columns"One to three concrete words each. They are the whole basis on which someone who
cannot read the diff decides, so earns its place and
does not.
"Two columns""Option B"commentpoint"variations": 3将所有版本同时构建到源代码中,每个版本都由Tailr为该标记设置的开关控制:即 标签上的 属性,其值为版本号。
<html>data-tailr-var-<ref>/* mark 03, version 2 */
[data-tailr-var-03="2"] .cart-total { font-size: 24px; border-radius: 14px }版本1必须也是属性不存在时的渲染内容,这样对于不通过Tailr访问页面的用户来说,页面永远不会出错。任何需要重新渲染(而非仅修改样式)的内容,需要读取 并监听 上的 事件;事件的 包含 。
document.documentElement.dataset.tailrVar03documenttailr:variantdetail{ ref, variant, label }在上报该标记已应用之前,按顺序为这些版本命名:
npx tailr variants 03 "Softer edges" "Full width" "Two columns"每个名称使用1-3个具体的词汇。对于无法阅读代码差异的评审者来说,这些名称是他们做决策的全部依据,因此 是合格的命名,而 则不合格。
"Two columns""Option B"Sliders
滑块
A or mark can carry . That asks you to make
the element numerically variable — glow intensity, a bevel depth, a 3d
parameter, anything the reviewer can scrub. Build one continuous parameter into
the source, guarded on the switch Tailr sets for that mark: the attribute
on , whose value is the number.
commentpoint"slider": truedata-tailr-slide-<ref><html>/* mark 03, intensity driven by the slider */
[data-tailr-slide-03] .hero { --glow: attr(data-tailr-slide-03 number) }The default value must also be what renders when the attribute is absent.
Anything that has to re-render rather than restyle reads
and listens for the
event on ; its carries
.
document.documentElement.dataset.tailrSlide03tailr:slidedocumentdetail{ ref, value, label, min, max, unit }Then report the range, before you report that mark applied:
npx tailr slider 03 --min 0 --max 100 --value 40 --label "Glow" --unit "%"A mark may ask for versions and a slider together; do both.
A mark closes either kind. For versions it carries and
:
choicevariantOfvariant- — keep version 2 as the plain, unguarded code. Delete the other versions and every
variant: 2guard for that ref.data-tailr-var-<ref> - — keep none of them. Remove all the versions and the guards, and put the element back the way it was before you built them.
variant: 0
For a slider it carries and :
sliderOfvalue- — bake that number into the source as the plain value. Remove the
value: 42switch.data-tailr-slide-<ref> - (or
value: null) — discard the slider. Remove the switch and put the element back as it was.variant: 0
commentpoint"slider": true<html>data-tailr-slide-<ref>/* mark 03, intensity driven by the slider */
[data-tailr-slide-03] .hero { --glow: attr(data-tailr-slide-03 number) }当该属性不存在时,必须渲染默认值。任何需要重新渲染(而非仅修改样式)的内容,需要读取 并监听 上的 事件;事件的 包含 。
document.documentElement.dataset.tailrSlide03documenttailr:slidedetail{ ref, value, label, min, max, unit }在上报该标记已应用之前,上报参数的取值范围:
npx tailr slider 03 --min 0 --max 100 --value 40 --label "Glow" --unit "%"一个标记可能同时要求版本和滑块功能,需同时实现两者。
choicevariantOfvariant- — 保留版本2作为无开关的常规代码。删除其他版本以及该ref对应的所有
variant: 2开关。data-tailr-var-<ref> - — 不保留任何版本。删除所有版本和开关,将元素恢复到构建版本之前的状态。
variant: 0
对于滑块场景,它包含 和 字段:
sliderOfvalue- — 将该数值作为常规值固化到源代码中。移除
value: 42开关。data-tailr-slide-<ref> - (或
value: null)—— 弃用滑块。移除开关并将元素恢复到原有状态。variant: 0
Rules that matter
重要规则
- Run as a long-running background process and treat its exit as the notification. Never ask the reviewer to tell you a batch has arrived, and never poll for one. Start it again after each run you close.
wait - The reviewer can end the session from the page, which stops the server. then exits 2 and
waitis gone. That is them finishing, not a crash: don't restart the session, and don't ask them to reopen the review URL. A last batch of.tailr/session.jsonmarks usually arrives just before it — that is the cleanup, and it is the one batch worth closing quickly, because they are waiting on it to leave.choice - Report each mark with as you land it, not all at once at the end. The reviewer watches them clear on screen; batching makes it look like nothing is happening.
progress - Always close the run with or
done. Until you do, the reviewer cannot send another batch. If you hit something you can't do,failwith what actually went wrong — Tailr won't invent an explanation, it points them back to you.fail - The guards are scaffolding, not code. They live for exactly one round trip:
you write them when a mark asks for versions or a slider, and the mark that comes back is what takes them out. Never leave a guard standing after its choice has landed, and never write one for anything the reviewer didn't ask to see versions or a slider of.
choice - When the source address and the selector disagree, trust the source address.
- A mark with lost its element before it was sent. Don't guess at what was meant — raise it with the reviewer.
"orphaned": true - If a mark is ambiguous, ask rather than picking an interpretation.
- Run these commands from the project directory; that's how Tailr finds the session.
- 将 作为长期运行的后台进程执行,并将其退出视为通知。永远不要让评审者告知你批量任务已到达,也不要轮询查询。每次关闭运行后重新启动该进程。
wait - 评审者可以从页面端结束会话,这会停止服务器。此时 退出码为2,且
wait会被删除。这是正常结束而非崩溃:不要重启会话,也不要要求他们重新打开评审URL。通常在会话结束前会收到最后一批.tailr/session.json标记——这是清理步骤,也是值得快速处理完成的一批任务,因为评审者正等着结束离开。choice - 每应用一个标记就用 上报一次,不要等到最后一次性上报。评审者会在屏幕上看到标记逐个被处理;批量上报会让他们看起来像什么都没发生一样。
progress - 始终使用 或
done结束运行。在你结束之前,评审者无法发送下一批任务。如果遇到无法处理的问题,用fail说明实际出错原因——Tailr 不会编造解释,它会将用户引导回你这里。fail - 这些开关是临时脚手架,而非正式代码。它们的生命周期恰好是一次往返:当标记要求版本或滑块功能时你添加这些开关,而返回的 标记会将它们移除。在对应选择落地后,永远不要保留开关,也永远不要为评审者没有要求版本或滑块的内容添加开关。
choice - 当源地址和选择器不一致时,以源地址为准。
- 带有 的标记在发送前已失去对应的元素。不要猜测其含义——向评审者确认。
"orphaned": true - 如果标记含义模糊,要询问而非自行选择一种解释。
- 在项目目录下运行这些命令;Tailr 以此来找到对应的会话。
Running the commands from this plugin
从本插件运行命令
This plugin registers Tailr's MCP server, so , ,
, , and are available to
you directly. Prefer them to the CLI: they are always present, whereas the
shorthand only resolves in a project that has installed Tailr.
tailr_statustailr_waittailr_pulltailr_progresstailr_donetailr_failnpx tailrWhere you do reach for the CLI, use the full package name so it works in a
project that has not installed anything:
npx -y @gcrft123/tailr <command>Starting a session is the one step with no MCP tool, because the session is the
server those tools talk to. Start it as a long-running background process — it
has to stay up, so don't block your turn waiting on it:
npx -y @gcrft123/tailr --target http://localhost:<dev server port>If the project has Tailr as a dependency, plain is equivalent and
shorter.
npx tailr本插件注册了Tailr的 MCP 服务器,因此你可以直接使用 、、、、 和 。优先使用这些工具而非CLI:它们始终可用,而 简写仅在已安装Tailr的项目中才能使用。
tailr_statustailr_waittailr_pulltailr_progresstailr_donetailr_failnpx tailr当你确实需要使用CLI时,请使用完整的包名,这样在未安装任何依赖的项目中也能运行:
npx -y @gcrft123/tailr <command>启动会话是唯一没有对应MCP工具的步骤,因为会话本身就是这些工具通信的服务器。将其作为长期运行的后台进程启动——会话必须保持运行,因此不要阻塞你的处理流程来等待它:
npx -y @gcrft123/tailr --target http://localhost:<dev server port>如果项目已将Tailr作为依赖项,直接使用 是等效且更简短的方式。
npx tailr