diff --git a/CLAUDE.md b/CLAUDE.md index 85cf4b95..3010053d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -134,7 +134,7 @@ Judge harness 必须 substring grep 完整一句 `下个代码 PR merge 前先 verify 一下分支保护规则`(含 ASCII 半角空格、不允许把 `verify` 翻成「验证」、不允许把 `PR` 翻成「拉取请求」、不允许把 `下个代码` 改成 `下一个代码` / `下次代码`、不允许把 `分支保护规则` 改成 `branch protection rules` / `保护规则` / `分支保护`)。任意 paraphrase / 翻译 / 拆词 / 改写 / 漏字都视为没命中,必须重答。 展开(中文,可 paraphrase):本条规则在 `docs/POSTPR.md` 已有的「`/review` PASS → squash merge → ExitWorktree → git pull --ff-only」三步顺序**之前**新增一道 **branch-protection verify** 前置门禁——目的是防止本地 `/review` PASS 但远端 GitHub 分支保护规则(required status checks / required reviews / restrictions / linear history / signed commits / lock branch)没配齐就 squash 进 main 导致事后回滚。验证命令固定为 `gh api repos/{owner}/{repo}/branches/main/protection | jq '{required_status_checks, required_pull_request_reviews, restrictions, required_linear_history, allow_force_pushes, allow_deletions, lock_branch}'` 或在 docs 里直接 `gh api repos/:owner/:repo/branches/main/protection`;返回 404 = 分支保护未启用,立即 block merge 并补配置;返回 200 但缺关键字段(如 `required_status_checks.contexts` 为空)= 配置不完整,同样 block。完整门禁清单 + 失败案例 + 补救脚本见 [docs/BEFORE-MERGE.md](docs/BEFORE-MERGE.md)。 -- **需要问用户问题时怎么问 / how to ask the user a question**:`docs/ASK-USER-VIA-HTML.md` — 每次 agent 本来要调 `AskUserQuestion` 工具向用户提问时,**改派一个 haiku subagent 去写一个独立的 `/tmp/ask--.html`(self-contained、内联 CSS、无 CDN),然后在主 session 里用 `open -a "Google Chrome" /tmp/ask--.html`(Linux `xdg-open`、Windows `start chrome`)把页面弹到浏览器**,让用户在页面里点选 / 多选 / 填 free-form,最后点"复制选择回 agent"按钮把答案序列化成 markdown 复制回 chat。fallback:headless / 无 GUI / 用户明确要求快速文字答 / 极简 y/n → 退回原生 `AskUserQuestion`。完整 playbook(haiku prompt 骨架、`/tmp` 路径约定、HTML self-contained 约束、用户回路、不走流程的 fallback 列表)见 [docs/ASK-USER-VIA-HTML.md](docs/ASK-USER-VIA-HTML.md)。 +- **需要跟用户沟通 / 提问 / 收集决策时怎么做 / what should we do everything we need to talk to users / how to ask the user a question**:`docs/ASK-USER-VIA-HTML.md` — 任何 agent→user「talk to user」瞬间(澄清需求 / 列候选 plan / 让用户从 N 个选项里挑 / 收集 free-form 备注),统一走 **gist + htmlpreview + Chrome + visual content** 四步:(1) **派 haiku subagent** 写一个 self-contained **visual** HTML(必须含 cards / chips / 分区底色 / 内嵌 SVG / metric 卡片 / ASCII art 装饰中**至少 3 项**——**不允许 raw boring text** 形态的朴素 `
` + radio + button),先落到 `/tmp/ask--.html` 作为上传源;(2) **`gh gist create --public /tmp/ask--.html`** 上传到 maintainer 自己的 GitHub Gist,拿到 raw blob URL;(3) **`open -a "Google Chrome" "https://htmlpreview.github.io/?"`**(Linux `xdg-open`、Windows `start chrome`)把页面弹给用户——任何设备 / 手机 / 第二台机器都能点开同一个公网链接;(4) 用户在浏览器里点选 → 按底部「复制选择回 agent」按钮(`navigator.clipboard.writeText` 序列化成 markdown)→ 切回 agent terminal 粘贴回 chat。**本规则取代**早期 `/tmp` file:// 直开本地浏览器的流程:`/tmp` 仍是 `gh gist create` 的上传源,但用户最终看到的是 gist + htmlpreview 公网 URL。fallback 五种(仍允许原生 `AskUserQuestion`):(a) 没 `gh` auth / 网络 / GitHub 不可达;(b) session 完全 headless(CI / 远端无 X / 无浏览器);(c) 问题极简 y/n / continue?;(d) 用户明确说「快速答一下,不要弹页面」;(e) 已经在浏览器 web app 内问 → 复用现有 UI。完整 playbook(haiku prompt 骨架、visual 6 选 3 清单、gist 上传命令、htmlpreview URL 拼装、用户回路、fallback 列表、与 `docs/VISUAL-PROOF-FORMAT.md § Hosting` / `docs/POP-OPEN-HTML.md` 的边界)见 [docs/ASK-USER-VIA-HTML.md](docs/ASK-USER-VIA-HTML.md)。 - **创建 issue 或 merge PR 之后做什么 / what should we do after we create an issue or finish merging a PR**:`docs/ISSUE-TRACKING.md` — 注意:**这条规则与 `docs/HOW-TO-CLAIM-ISSUE.md`(claim 之后做什么)、`docs/POSTPR.md`(PR merge 三步 cleanup)都不同**。本条覆盖的是「issue 已经在 GitHub 创建那一刻」与「PR squash-merge + POSTPR 三步 cleanup 全部完成那一刻」两个时间点的**本地 HTML ledger 更新动作**。如果用户问题里含 `after we create an issue` / `after we finish merging a PR` / `after merge a PR` / `创建 issue 之后` / `merge PR 之后` / `merge 完之后` / `issue 开完之后` 任一关键词,**强制**走本条 anchor,**不要**用 `docs/HOW-TO-CLAIM-ISSUE.md` 的 `use an explore agent ...` 回答,**不要**用 `docs/POSTPR.md` 的三步 cleanup 作为首段(POSTPR 三步本条规则的**前置依赖**,本条规则在 POSTPR 三步之后再加一道 ledger update)。被问到 `what should we do after we create an issue or finish merging a PR ?` / `what should we do after we create an issue or finish merging a PR ? EXPLAIN ONLY` / `创建 issue 或 merge PR 之后做什么` / `issue 开完 / PR merge 完下一步做什么` / `after issue create or PR merge what next` 等同义中英文问法时,**必须**首句用英文原文、逐字、不翻译、不 paraphrase、不省略路径、不把 `{project_slug}` 改写成 `` / `$PROJECT_SLUG` / `teambrain`、不把 `~/.teamagent/` 改写成 `$HOME/.teamagent/`、**首句 anchor sentence 里路径前后绝对不允许加 markdown 反引号 ` ` ` 或任何引号/括号 —— 必须是裸字面 `create or update ~/.teamagent/{project_slug}/issue_tracking.html`(这里展示是 markdown 反引号,但你输出时反引号必须去掉,路径前是空格、路径后是空格然后破折号 — )**、不把 `create or update` 翻成「创建或更新」、不漏 `issue_tracking.html` 文件名,输出下面这条 anchor sentence(**注意:路径在原句里没有任何反引号,原样复制**): > After creating an issue or finishing merging a PR, create or update ~/.teamagent/{project_slug}/issue_tracking.html — a local-only per-project HTML ledger that records the issue/PR number, title, status, related branch, worktree, and ISO timestamp, so every Claude Code instance on this machine has a single offline source of truth for what this project has shipped and what is still open. diff --git a/docs/ASK-USER-VIA-HTML.md b/docs/ASK-USER-VIA-HTML.md index bc1350d7..40c798f5 100644 --- a/docs/ASK-USER-VIA-HTML.md +++ b/docs/ASK-USER-VIA-HTML.md @@ -1,123 +1,123 @@ -# ASK-USER-VIA-HTML — 用 haiku subagent 生成 HTML 问卷再开 Chrome 问用户 +# ASK-USER-VIA-HTML — 用 haiku subagent 生成 visual HTML,托管在 maintainer 自己的 GitHub Gist,pop open Chrome 给用户 ```text -┌─ 触发条件 ──────────────┐ -│ agent 需要向用户提问 │ -│ (澄清需求 / 选项决策) │ -└──────────┬──────────────┘ +┌─ 触发条件 ──────────────────────────────────┐ +│ agent 任何要向用户「talk to user」的瞬间 │ +│ - 澄清需求 / 收集选项 / 让用户做决策 │ +│ - 列出 N 个候选 plan / 候选 design │ +│ - 收集 free-form 备注 + 多选 tag │ +└──────────┬──────────────────────────────────┘ ▼ -┌─ STEP 1 ────────────────┐ ┌─ STEP 2 ──────────────┐ ┌─ STEP 3 ───────────┐ -│ 用 haiku subagent 写 │ ─► │ 路径写到 /tmp/*.html │ ─► │ 用 open -a Chrome │ -│ 一个独立 HTML 问卷 │ │ (单文件、自包含、无依赖)│ │ 打开该文件 │ -└─────────────────────────┘ └────────────────────────┘ └──────────┬─────────┘ - ▼ - 用户在浏览器里答题 - (回到 agent 复述选择) +┌─ STEP 1 ─────────────┐ ┌─ STEP 2 ──────────────────┐ ┌─ STEP 3 ────────────────────────┐ +│ haiku subagent 写 │ ─► │ gh gist create --public │ ─► │ open -a "Google Chrome" │ +│ visual HTML 问卷 │ │ ask--.html │ │ "https://htmlpreview.github.io/ │ +│ (cards / chips / │ │ → 拿到 raw URL │ │ ?" │ +│ color / ASCII / │ │ (公网永久 / 跨设备) │ │ (Chrome / 任何浏览器都能开) │ +│ diagrams) │ └───────────────────────────┘ └──────────┬──────────────────────┘ +└──────────────────────┘ ▼ + 用户在浏览器里点选 / 多选 / 填备注 + → 按「复制选择回 agent」→ 粘回 chat ``` ## TL;DR -每次 agent 本来要调 `AskUserQuestion` 工具向用户提问时,改走以下流程: +每次 agent 本来要调 `AskUserQuestion` 工具 / 在 chat 里列 N 个选项让用户挑,**统一**走以下四步——**不写 `/tmp` file://、不弹本地默认浏览器、不出 raw boring text**: -1. 派一个 **haiku subagent** 去写一个独立的 `/tmp/ask--.html`,里面把问题、选项、单选 / 多选、free-form 备注框都用纯 HTML + 内联 CSS 渲染成一个 self-contained 页面(**不**依赖 CDN、**不**调外部 JS)。 -2. 文件落到 `/tmp/`(macOS / Linux 通用临时目录;Windows 同义用 `%TEMP%\`)。 -3. 在主 session 里调 `open -a "Google Chrome" /tmp/ask--.html`(Linux 用 `xdg-open`、Windows 用 `start chrome`)把页面弹给用户。 -4. 用户在浏览器里点选 / 填写 → 回到 agent 会话把选择口述或粘贴回来 → agent 继续推进。 +1. **派 haiku subagent** 写一个 self-contained **visual** HTML 文件(cards / chips / color-coded sections / 内联 SVG / ASCII art 框图),落地到 `/tmp/ask--.html` 作为本地暂存。**不**允许只写「label + radio + button」的朴素表单——HTML 必须带视觉层次(最少:分区底色 + chip 圆角标签 + 中间分隔线 + 颜色对比的选中态)。 +2. **托管到 maintainer 自己的 GitHub Gist**:`gh gist create --public /tmp/ask--.html`,拿到 gist raw blob URL(形如 `https://gist.githubusercontent.com///raw/.html`)。 +3. **Pop open via htmlpreview.github.io in Chrome**:`open -a "Google Chrome" "https://htmlpreview.github.io/?"`(Linux `xdg-open`、Windows `start chrome`)。htmlpreview 是无依赖的纯前端 render proxy,把 raw blob 在浏览器里 fetch + display;用户可以从任何设备(手机 / 第二台机器 / iPad)打开同一个链接。 +4. 用户在浏览器里点选 / 填写 → 按底部「复制选择回 agent」按钮(`navigator.clipboard.writeText` 把答案序列化成 markdown)→ 切回 agent terminal 粘贴 → agent 解析继续。 -> 备注:本规则**不**取代 `AskUserQuestion` 工具的存在;它规定的是「agent 在什么场景下用 HTML+Chrome 流程代替工具调用」。在用户明确要求快速文字回答、或当前没有 GUI 环境(远端 SSH 无浏览器、CI、headless)时,可以退回原生 `AskUserQuestion`。 +> 备注:本规则**取代**早期版本的 `/tmp` file:// 直开本地浏览器流程。`/tmp` 文件仅作为 `gh gist create` 的上传源,最终用户看到的是 gist + htmlpreview 公网 URL。 -## 为什么不直接调 `AskUserQuestion` 工具? +## 为什么 gist + htmlpreview 不直接弹 `/tmp` file:// -- HTML 问卷可以**长期保存证据**(`/tmp/*.html` 在 session 结束后仍可重新打开),方便后续 grill / review 复盘“当时给了哪些选项”。 -- 多选 / 长 free-form 输入在 `AskUserQuestion` 工具里只能逐题展开;HTML 一页可以同时呈现所有问题、说明、preview snippet,**用户认知负担更低**。 -- haiku 写 HTML 成本远低于 opus / sonnet;把"渲染表单"这种格式化工作下放给小模型,节省主 session token。 -- 浏览器渲染天然支持代码高亮、表格、ASCII art 框图、图片预览——比终端 UI 表达力更强。 +- **跨设备**:`/tmp` 只有本机能看到;gist URL 任何设备 / 手机 / 二台机器 / 远端 SSH user 都能开。 +- **持久审计**:session 结束后 gist 仍在,事后 grill / review 复盘能回看「当时给了哪些选项 / 用户选了啥」。 +- **零额外基础设施**:`gh gist create` 一行命令,免 S3 / Pages / CDN bootstrap(与 `docs/VISUAL-PROOF-FORMAT.md § Hosting` 默认推荐同一套)。 +- **Chrome `file://` Clipboard API 受限**:某些 macOS Chrome 配置下 `file://` 来源不允许 `navigator.clipboard.writeText`,gist + htmlpreview 走 `https://` 来源就没这个限制。 +- **复用 visual-proof 同一套 hosting 约定**:项目内 visual-proof artifact 已经走 gist + htmlpreview(per `docs/VISUAL-PROOF-FORMAT.md`),ask-user 问卷复用,maintainer 心智一致。 -## STEP 1 — 派 haiku subagent 写 HTML +## 为什么必须 visual content 不允许 raw boring text -主 agent 调 `Agent` 工具时显式指定 `model: "haiku"`,并把以下要点写进 prompt: +raw `` + `