Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/lazygophers/ccplugin --skill ask-ui명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
记忆库升降级维护 — 按金字塔模型 (L4 庞大 → L0 稠密) 自动 promote/demote. 信号: 频率 (近期提及) / 时间 (距今) / 重要度. 规则: 用户反复强调 → 逐级升; L1/L0 允许自动升不允许自动降. 主要工作区 L4-L2; 默认 --apply 落盘 (--dry-run opt-in 预览). 无独立脚本, 调 cortex-extract/save/lint 执行.
extract/提取/promote/整理/归档/digest L4-inbox 收件箱, 按三轴 (抗遗忘度/强度/复用面) 路由到 L1-long/L2-mid/L3-short/项目/领域, 默认 --apply 落盘 + 增量游标 (--dry-run opt-in 仅出 JSON plan 预览). 触发词: 整理 inbox / 提取记忆 / 归档笔记 / promote / digest.
Claude Code 会话历史整理 — 扫 ~/.claude/projects/**/*.jsonl 全部 session transcripts, 提取学习增量 (用户校正/决策/踩坑/L0 规则) → 全局记忆库 ~/.cortex/.wiki/memory/. 默认 --apply 落盘 (--dry-run opt-in 仅出 JSON plan 预览). 与 cortex-extract (L4-inbox 内部) 互补.
| name | ask-ui |
| description | 向用户提问的时候、调用 `AskUserQuestion` 时都使用本 skill 来替换提问方式 |
把 Ask UI 当作展示与持久化适配器使用。问题的生成和推理仍留在调用方工作流里。
| 路径 | 何时走 | 答案怎么回来 |
|---|---|---|
标准路径 ask | 默认。后台运行,阻塞到用户提交 | 进程退出,harness 推完成通知,读 stdout 文件 |
故障恢复 resume | 仅「故障速查」表列出的情况 | status: "submitted" 里就是完整答案 |
手动回退 create | ask 确实用不了的最后手段 | 用户回复「已提交」后跑 resume |
选错路径的代价都在后文用 🔴 标出。先读总览再往下走,不要跳进某条路径的细节里出不来。
无论走到哪条路径,以下红线一次都不能破:
ask——后台任务的完成通知就是唤醒信号。ask。nohup ... & 之类手写后台——用 harness 自己的后台机制。sleep 轮询、催用户。.ask-ui/ 下的文件路径——答案读 <run>.stdout.json,或跑 resume。🔴 CHECKPOINT:当前一批问题里包含至少两个用户当下就能回答的独立问题时,必须使用 UI。答案依赖前一题的问题写成同一次提问里的条件题(showWhen,见第 3 步);只有需要 Agent 拿到答案后重新推理才能提出的问题,才留到下一次 ask。只有一个问题时直接在对话里问;唯一的例外是更正或补充已提交的答案——哪怕只有一题也再发起一次 ask,因为对话里口头确认不落盘,后续流程读不到它。
对 grill-me、grill-with-docs、头脑风暴,或其他确认与问题收集类工作流,只要一次超过两个问题,一律使用 UI。
按顺序往下退,退到能用的第一档为止:
AskUserQuestion——本 skill 用不了时改用它。用不了的情形有两种:harness 没有可执行命令的工具(Bash 或等价物),或服务/浏览器确实起不动。AskUserQuestion 也拿不到时才允许。退档时说清真实原因,别把「没有 Bash 工具」写成「服务起不来」——前者换任何语言重写都没用,后者才是环境问题。用 ToolSearch 确认过工具确实不存在,再下结论。
ask 八步把包含本 SKILL.md 的目录解析为 ASK_UI_SKILL_DIR。
创建 JSON 前先读两份文件:references/questionset.schema.json 是字段清单本身(JSON Schema 2020-12,每个字段带中文说明),references/schema.md 讲 schema 表达不了的部分——跨字段硬规则、页面实际行为、为什么这样写。references/example-question-set.json 是一份可直接复制改字段的完整起手模板(单选 / 多选 / 自由文本各一题,带推荐答案和上下文字段)。答案的结构见 references/answerset.schema.json。
创建 QuestionSet JSON 文件。每次 ask 都是一次独立提问,id 由 CLI 自动生成。旧版字段(sessionId / roundNumber / basedOnRound / sessionTitle / sessionSummary / sessionBackground)已全部移除,写了会报错指路。
每道题必写两个字段:type(single / multiple / text,没有默认值,漏写报错)和 text(问题正文,问题本身和描述都写在这里)。选项一律是 JSON 对象 {"text":"…","description":"…","recommended":true,"reason":"…"},不接受字符串;reason 只能写在 recommended: true 的选项上。
允许留空的题必须显式写 "required": false——required 默认 true,漏写就是必填,页面挂「必填」徽标、留空挡提交。别在 text 里写「(可留空)」代替这个字段:文案和徽标对不上,用户只能被迫编一句。「还有别的补充吗」「其他备注」「可选参数」这类题一律 type: "text" + "required": false。
一并写上上下文字段,让用户不看对话就能判断在问什么:projectName / title / summary / background(左栏「本次背景」,右上角有独立按钮可放大)/ purpose,需要单独交代前情的题写题级 background。
选择题没有「其他」选项。预设选项之外的答案由每题的补充说明承载,所以选项只列真正互斥的几种,不要凑「其他」。选择题至少要 2 个选项,脚本会直接报错 第 X 题是选择题,至少要有两个选项 并退出——只有一个候选的确认题改成 type: "text",或者干脆在对话里问。
有依赖关系的问题写成同一次提问里的条件题:"showWhen": {"questionId":"q1","optionIds":["a"]} 让这题只在 q1 选了 a 时才出现,用户选完当场出现或消失。showWhen 只能指向排在前面的题,分支树靠链式依赖搭;文本题作触发源时用 answered / contains / matches。隐藏题不校验必填、也不进 answers.json(id 列在 hiddenQuestionIds)。完整规则见 references/schema.md 的「条件题(分支)」——showWhen 的三条跨字段硬规则(指向前面的题、匹配方式配得上题型、选项 id 真实存在)schema 拦不住,只有运行时会报错。
background、题目的 text 和 background 支持 Markdown(GFM:标题、粗体、行内代码、代码块、列表、链接、引用、表格)+ Mermaid;选项的 description 只支持 Markdown。流程、时序、架构这类讲不清的东西写成 ```mermaid 代码块,会渲染成跟随主题的图。表格、图表和代码块在页面上都能点击放大、缩放拖拽。代码块在围栏上标语言(```ts、```sql)就会按语言高亮。嵌套规则:要展示一段本身含 围栏的 markdown(或代码里含)时,外层围栏必须用四反引号 ````——三反引号会被内层第一个 提前闭合,后面的内容漏成正文,页面上出现裸 字符。
在后台运行命令,只把 stdout 重定向到文件,stderr 留在控制台:
node <ASK_UI_SKILL_DIR>/scripts/ask-ui.mjs ask --input <questions.json> > <run>.stdout.json
用 harness 的后台机制启动(Claude Code 里是 Bash 工具的 run_in_background: true)。stdout 是结果 JSON,必须落文件;stderr 是给人看的进度行(URL、ask-ui-id),留在控制台用户当场就能看到。
**把页面 URL 复述到回复第一行。**stderr 启动时立刻打出 Ask UI ready at <url> 和 ask-ui-id: <id>,用 TaskOutput 读一次后台任务输出取这两行写进回复。浏览器是脚本自动打开的,但它可能没弹出来(无 GUI、默认浏览器没配、窗口被挡),URL 摆出来用户就能自己打开。读一次就够,读不到就照常结束本轮,不要 sleep 重试。
🛑 STOP:输出 URL 后立刻结束本轮,什么都不用等。ask 没有超时,会一直阻塞到用户提交;用户提交后进程退出,harness 主动把任务完成通知推给你,那就是唤醒信号。
收到完成通知后,直接读 <run>.stdout.json——它是一整行 JSON,解析后继续原工作流。
若还需要更多独立问题,再创建一份 QuestionSet JSON 并再次调用 ask——每次 ask 天然独立,互不干扰。
不重定向时,后台任务的 stdout 和 stderr 会混进 harness 的同一个任务输出,混在一起的内容 JSON.parse 必然失败——这是过去要人工 resume 兜底的唯一原因。把 stdout 单独 > 到文件后,结果 JSON 就是纯净的一行,任务输出里只剩 stderr 的进度行(URL、ask-ui-id、ask-ui-submitted),既能给人看又不会污染解析。
ask 都会打开浏览器:页面在提交后自行关闭,所以下一次提问必须重新打开。常驻服务和端口在多次提问间复用。--no-open。仅当必须固定 localhost 端口时才用 --port <number>。node <ASK_UI_SKILL_DIR>/scripts/ask-ui.mjs resume --id <askId>
🔴 只有下表列出的情况才需要 resume。正常路径永远是读 <run>.stdout.json,不要把 resume 当常规动作。
askId 从任务输出(stderr)里的 ask-ui-id: <id> 标记取;那里还有一行 ask-ui-submitted: <id>,是提交完成的备用信号。resume 返回 status: "submitted" 时其中就是完整答案。
| 触发条件 | 一线修复 | 仍失败的兜底 |
|---|---|---|
任务秒退,任务输出里连 ask-ui-id 标记都没有 | QuestionSet JSON 非法,提问根本没建起来:读任务输出里的报错(一次列出全部问题)改 JSON 重跑 ask | 🔴 不要跑 resume——没有数据可恢复,不带 --id 的 resume 只会捞出别的任务的旧提问 |
后台任务被杀、崩溃,或退出码非 0(任务输出有 ask-ui-id) | 取 askId 后跑 resume | 跑不带 --id 的 resume,按 title / summary 筛出讲当前任务的候选,取 submittedAt 最新的一条 |
<run>.stdout.json 为空或不是合法 JSON | 同上,用 resume 重取结果 | 数据确实不存在时据实说明答案已丢,用同一批问题重新 ask |
| 换了新的 Agent 会话,拿不到原来的后台任务 | 从对话里最近的 ask-ui-id 标记取 id 后 resume | 标记也丢了就跑不带 --id 的 resume 列候选 |
resume 返回 {"status":"waiting"} | 用户还没提交:什么都不做,当场结束本轮,继续等 harness 的完成通知 | 🔴 不重开表单、不重发问题、不催用户、不 sleep |
| 表单挂了很久没人答,担心服务一直占着 | 什么都不做:有提问等着答服务就该一直跑,全部答完后 30 分钟无访问自行退出,数据目录被删立即退出,complete / cancel 结束最后一个提问时当场停掉 | 🔴 不要手动 kill 进程;空闲时长要改就用 ASK_UI_IDLE_TIMEOUT_MINUTES |
| 本地浏览器连不上临时服务 | 走 create 分离式流程(见「手动回退与恢复」) | 仍连不上才退到 AskUserQuestion |
| harness 没有 Bash 或等价的执行工具 | 用 ToolSearch 确认工具确实不存在,退到 AskUserQuestion | AskUserQuestion 也拿不到时才用对话里的编号文本问题 |
| 唤醒适配器失败 | 保住答案,回到手动「已提交」流程 | 答案已落盘,用 resume 重取 |
🔴 CHECKPOINT:这是最后手段,只在 ask 确实用不了时才走——它是唯一需要用户回复「已提交」的路径。ask 在后台运行不算用不了,那是标准路径,按上面等通知即可。
出现以下情况时走分离式(detached)流程:前台工具调用无法保持活跃、本地浏览器连不上临时服务、或需要恢复一个被中断的直连提问:
node <ASK_UI_SKILL_DIR>/scripts/ask-ui.mjs create --input <questions.json>
解析返回的 JSON。在对话中同时给出它的 URL 和一个可见标记:
ask-ui-id: <askId>
告诉用户提交表单后只回复「已提交」。create 命令会启动或复用一个分离式 localhost 服务并立即返回。
当用户说「已提交」「提交好了」「答完了」时:
从对话中最近一个 ask-ui-id 标记恢复 askId。
运行:
node <ASK_UI_SKILL_DIR>/scripts/ask-ui.mjs resume --id <askId>
若结果为 submitted,用其中的问题和答案继续原工作流。
若还需要更多独立问题,优先回到前台 ask 命令(新的 JSON、新的提问)。只有在仍然无法直连等待时才再次使用 create。
若没有更多问题,运行:
node <ASK_UI_SKILL_DIR>/scripts/ask-ui.mjs complete --id <askId>
若对话中拿不到该标记,运行不带 --id 的 resume。多个候选时它返回 status: "ambiguous" 和一份 candidates 列表(含 askId / title / summary / workspace / submittedAt)。数据目录默认就是当前工作目录下的 .ask-ui,所以候选都来自本工作区。按这个顺序筛:
title 和 summary 筛,只保留讲的是当前任务的候选。submittedAt 最新的那条。askId、title、submittedAt 列出来让用户选,不要挑一个最近的凑合用。🔴 重复的「已提交」消息不得重复创建提问。只有在成功读到一个 submitted 的答案集之后,才可以发起新提问。
Ask UI 为 Claude Code 和 Codex App Server 支持可选的唤醒元数据。把它当增强项,不是必需项。
ask 模式永远不触发唤醒适配器,因为等待中的进程本身就是返回通道。每次准备发命令或回话之前,对照一遍。
| 🔴 不要做 | 为什么 | 改成 |
|---|---|---|
用 nohup ... & 之类手写后台 | harness 收不到退出事件,整条链路退回人工追问 | 用 harness 自己的后台机制 |
| stdout 不重定向,直接从任务输出解析结果 | 两股输出混在一起,JSON.parse 必然失败 | > <run>.stdout.json,stderr 留在控制台 |
| 把 stderr 也重定向进文件 | URL 和 ask-ui-id 被埋进文件,用户看不到,页面没弹出来就没法自己打开 | 只重定向 stdout |
sleep 轮询、催用户、让用户回复「已提交」 | 后台任务的完成通知就是唤醒信号,等它即可 | 启动后立刻结束本轮 |
从任务输出里找答案,或手拼 .ask-ui/ 路径 | 任务输出只有 stderr 的进度行,答案不在那里 | 答案读 <run>.stdout.json 或跑 resume;任务输出只用来取 URL、ask-ui-id 和报错 |
| 给选择题加「其他」选项 | 预设外的答案由每题的补充说明承载 | 选项只列真正互斥的几种 |
| 写只有一个选项的选择题 | 脚本硬拒收,整批问题连会话都建不起来 | 补足第二个真实互斥的选项,或改成 type: "text" |
在 text 里写「(可留空)」却不写 "required": false | required 默认 true,页面照挂「必填」徽标、留空挡提交,文案和校验对不上 | 选填题显式写 "required": false |
漏写 type,或把选项写成字符串 | 两者都硬拒收,整批问题连会话都建不起来 | type 三选一必写;选项一律写成带 text 的 JSON 对象 |
用题级 recommendedOptionIds 标推荐 | 已经不认这个字段,脚本会报错 | 推荐写在选项里:"recommended": true 配 "reason" |
让 showWhen 指向排在后面的题 | 顺序即依赖序,向后引用会被硬拒收 | 把触发题排到前面 |
| 因为「问题有依赖」就拆成多次 ask | 每次都要重开浏览器、Agent 也要多醒一次 | 同一次提问里用 showWhen 做分支 |
| 覆盖已提交的问题或答案 | answers.json 提交后不可变 | 更正和补充再发起一次 ask |
| 把「没有 Bash 工具」说成「服务起不来」 | 归因错了,用户会去修一个不存在的环境问题 | 说清是工具缺失还是服务故障 |
| 猜 Codex thread id | 猜错会把唤醒发给别的会话 | thread id 只能由宿主提供,拿不到就走手动流程 |
node <ASK_UI_SKILL_DIR>/scripts/ask-ui.mjs ask --input <questions.json> # 标准路径
node <ASK_UI_SKILL_DIR>/scripts/ask-ui.mjs create --input <questions.json> # 手动回退
node <ASK_UI_SKILL_DIR>/scripts/ask-ui.mjs resume --id <askId> # 故障恢复
node <ASK_UI_SKILL_DIR>/scripts/ask-ui.mjs status --id <askId> # 查提问状态
node <ASK_UI_SKILL_DIR>/scripts/ask-ui.mjs serve # 常驻服务(ask/create 自动管理,一般不单跑)
node <ASK_UI_SKILL_DIR>/scripts/ask-ui.mjs complete --id <askId> # 正常结束提问
node <ASK_UI_SKILL_DIR>/scripts/ask-ui.mjs cancel --id <askId> # 作废提问(问题问错了、任务取消)
node <ASK_UI_SKILL_DIR>/scripts/self-test.mjs # 自检,改完 skill 或排查环境时跑