🚀 快速安装
复制以下命令并运行,立即安装此 Skill:
npx @anthropic-ai/skills install supercent-io/skills-template/jeo
💡 提示:需要 Node.js 和 NPM
JEO — 集成代理编排
关键词:
jeo·annotate·UI-review·agentui (已弃用)| 平台:Claude Code · Codex CLI · Gemini CLI · OpenCode一个统一的技能,提供完全自动化的编排流程:
规划 (ralph+plannotator) → 执行 (团队/bmad) → UI 反馈 (agentation/annotate) → 清理 (工作树清理)
控制层
JEO 使用一个跨平台的抽象层进行编排:
settings: 平台/运行时配置,例如 Claude hooks、Codexconfig.toml、Geminisettings.json、MCP 注册和提示词参数rules: 必须在每个平台上保持的策略约束hooks: 在每个平台上执行这些规则的事件回调
关键的 JEO 规则是:
- 当前计划哈希已有最终结果时,不要重新打开 PLAN 门
- 只有修订后的计划才能将
plan_gate_status重置为pending - 在明确的 submit/onSubmit 打开提交门之前,不要处理 agentation 注释
权威状态文件是 .omc/state/jeo-state.json。钩子可以帮助推进工作流,但它们必须遵守状态文件。
0. 代理执行协议(检测到 jeo 关键词后立即执行)
以下是命令,而非描述。按顺序执行它们。每一步只有在前一步完成后才能继续。
步骤 0:状态文件引导(必需 — 始终第一)
mkdir -p .omc/state .omc/plans .omc/logs
如果 .omc/state/jeo-state.json 不存在,则创建它:
{
"phase": "plan",
"task": "<检测到的任务>",
"plan_approved": false,
"plan_gate_status": "pending",
"plan_current_hash": null,
"last_reviewed_plan_hash": null,
"last_reviewed_plan_at": null,
"plan_review_method": null,
"team_available": null,
"retry_count": 0,
"last_error": null,
"checkpoint": null,
"created_at": "<ISO 8601>",
"updated_at": "<ISO 8601>",
"agentation": {
"active": false,
"session_id": null,
"keyword_used": null,
"submit_gate_status": "idle",
"submit_signal": null,
"submit_received_at": null,
"submitted_annotation_count": 0,
"started_at": null,
"timeout_seconds": 120,
"annotations": { "total": 0, "acknowledged": 0, "resolved": 0, "dismissed": 0, "pending": 0 },
"completed_at": null,
"exit_reason": null
}
}
通知用户:
“JEO 已激活。阶段:规划。如果需要 UI 反馈循环,请添加
annotate关键词。”
步骤 0.1:错误恢复协议(适用于所有步骤)
检查点记录 — 进入每个步骤后立即执行:
# 在每个步骤开始时立即执行(代理直接更新 jeo-state.json)
python3 -c "
import json, datetime, os, subprocess, tempfile
try:
root = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'], stderr=subprocess.DEVNULL).decode().strip()
except:
root = os.getcwd()
f = os.path.join(root, '.omc/state/jeo-state.json')
if os.path.exists(f):
import fcntl
with open(f, 'r+') as fh:
fcntl.flock(fh, fcntl.LOCK_EX)
try:
d = json.load(fh)
d['checkpoint']='<当前阶段>' # 'plan'|'execute'|'verify'|'cleanup'
d['updated_at']=datetime.datetime.utcnow().isoformat()+'Z'
fh.seek(0)
json.dump(d, fh, ensure_ascii=False, indent=2)
fh.truncate()
finally:
fcntl.flock(fh, fcntl.LOCK_UN)
" 2>/dev/null || true
last_error 记录 — 在预检失败或异常时:
python3 -c "
import json, datetime, os, subprocess, fcntl
try:
root = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'], stderr=subprocess.DEVNULL).decode().strip()
except:
root = os.getcwd()
f = os.path.join(root, '.omc/state/jeo-state.json')
if os.path.exists(f):
with open(f, 'r+') as fh:
fcntl.flock(fh, fcntl.LOCK_EX)
try:
d = json.load(fh)
d['last_error']='<错误消息>'
d['retry_count']=d.get('retry_count',0)+1
d['updated_at']=datetime.datetime.utcnow().isoformat()+'Z'
fh.seek(0)
json.dump(d, fh, ensure_ascii=False, indent=2)
fh.truncate()
finally:
fcntl.flock(fh, fcntl.LOCK_UN)
" 2>/dev/null || true
重启时基于检查点的恢复:
# 如果 jeo-state.json 已存在,从检查点恢复
python3 -c "
import json, os, subprocess
try:
root = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'], stderr=subprocess.DEVNULL).decode().strip()
except:
root = os.getcwd()
f = os.path.join(root, '.omc/state/jeo-state.json')
if os.path.exists(f):
d=json.load(open(f))
cp=d.get('checkpoint')
err=d.get('last_error')
if err: print(f'之前的错误:{err}')
if cp: print(f'从以下阶段恢复:{cp}')
" 2>/dev/null || true
规则:在预检中
exit 1之前,始终更新last_error并递增retry_count。
如果retry_count >= 3,询问用户是否中止。
步骤 1:规划(从不跳过)
预检(进入前必需):
# 记录检查点
python3 -c "
import json,datetime,os,subprocess,fcntl,tempfile
try:
root=subprocess.check_output(['git','rev-parse','--show-toplevel'],stderr=subprocess.DEVNULL).decode().strip()
except:
root=os.getcwd()
f=os.path.join(root,'.omc/state/jeo-state.json')
if os.path.exists(f):
with open(f,'r+') as fh:
fcntl.flock(fh,fcntl.LOCK_EX)
try:
d=json.load(fh)
d.update({'checkpoint':'plan','updated_at':datetime.datetime.utcnow().isoformat()+'Z'})
fh.seek(0); json.dump(d,fh,ensure_ascii=False,indent=2); fh.truncate()
finally:
fcntl.flock(fh,fcntl.LOCK_UN)
" 2>/dev/null || true
# 注意:Claude Code — 跳过整个 bash 块。
# plannotator 是一个仅钩子的二进制文件;直接调用它总是失败。
# 对于 Claude Code:调用 EnterPlanMode → 编写计划 → 调用 ExitPlanMode。
# ExitPlanMode PermissionRequest 钩子会自动触发 JEO Claude 计划门包装器。
# 该包装器必须在当前计划哈希已有最终审查结果时跳过重新进入。
# 等待钩子返回再继续 — 批准或反馈将通过钩子结果到达。
# 以下脚本仅适用于 Codex / Gemini / OpenCode。
# 守卫:通过计划哈希防止重复的 PLAN 审查。
# 相同的哈希 + 最终门状态 => 跳过重新打开计划门
# 修订后的 plan.md 内容 => 将门状态重置为 pending 并再次审查
PLAN_GATE_STATUS=$(python3 -c "
import json, os
try:
s = json.load(open('.omc/state/jeo-state.json'))
print(s.get('plan_gate_status', 'pending'))
except Exception:
print('pending')
" 2>/dev/null || echo "pending")
HASH_MATCH=$(python3 -c "
import hashlib, json, os
try:
s = json.load(open('.omc/state/jeo-state.json'))
if not os.path.exists('plan.md'):
print('no-match')
else:
current_hash = hashlib.sha256(open('plan.md', 'rb').read()).hexdigest()
print('match' if current_hash == (s.get('last_reviewed_plan_hash') or '') else 'no-match')
except Exception:
print('no-match')
" 2>/dev/null || echo "no-match")
if [[ "$HASH_MATCH" == "match" && "$PLAN_GATE_STATUS" =~ ^(approved|manual_approved|feedback_required|infrastructure_blocked)$ ]]; then
echo "✅ 当前计划哈希已有门结果:$PLAN_GATE_STATUS。不要重新打开 plannotator。"
exit 0
fi
# plannotator 对于 PLAN 步骤是强制性的(Codex/Gemini/OpenCode)。
# 如果缺失,JEO 会在打开 PLAN 门之前自动安装它。
# 解析 JEO 脚本目录(从任何 CWD 工作)
_JEO_SCRIPTS=""
for _candidate in \
"${JEO_SKILL_DIR:-}/scripts" \
"$HOME/.agent-skills/jeo/scripts" \
"$HOME/.codex/skills/jeo/scripts" \
"$(pwd)/.agent-skills/jeo/scripts" \
"scripts" \
; do
if [ -f "${_candidate}/plannotator-plan-loop.sh" ]; then
_JEO_SCRIPTS="$_candidate"
break
fi
done
if [ -z "$_JEO_SCRIPTS" ]; then
echo "❌ 未找到 JEO 脚本。重新运行:bash setup-codex.sh(或 setup-gemini.sh)"
exit 1
fi
if ! bash "${_JEO_SCRIPTS}/ensure-plannotator.sh"; then
echo "❌ plannotator 自动安装失败:无法继续 PLAN 步骤。"
echo " 重试:bash ${_JEO_SCRIPTS}/../scripts/install.sh --with-plannotator"
exit 1
fi
# 必需的 PLAN 门(Codex / Gemini / OpenCode):
# - 必须等待直到收到批准/反馈
# - 会话退出时自动重启(最多 3 次)
# - 3 次退出后,询问用户是否结束 PLAN
FEEDBACK_DIR=$(python3 -c "import hashlib,os; h=hashlib.md5(os.getcwd().encode()).hexdigest()[:8]; d=f'/tmp/jeo-{h}'; os.makedirs(d,exist_ok=True); print(d)" 2>/dev/null || echo '/tmp')
FEEDBACK_FILE="${FEEDBACK_DIR}/plannotator_feedback.txt"
bash "${_JEO_SCRIPTS}/plannotator-plan-loop.sh" plan.md "$FEEDBACK_FILE" 3
PLAN_RC=$?
if [ "$PLAN_RC" -eq 0 ]; then
echo "✅ 计划已批准"
elif [ "$PLAN_RC" -eq 10 ]; then
echo "❌ 计划未批准 — 应用反馈,修订 plan.md,然后重试"
exit 1
elif [ "$PLAN_RC" -eq 32 ]; then
echo "⚠️ plannotator UI 不可用(沙箱/CI)。进入对话批准模式:"
echo " 1. 在对话中向用户输出 plan.md 内容"
echo " 2. 询问用户:'批准' 继续或提供反馈"
echo " 3. 在用户明确批准之前,不要进入执行步骤"
exit 32
elif [ "$PLAN_RC" -eq 30 ] || [ "$PLAN_RC" -eq 31 ]; then
echo "⛔ PLAN 退出决定(或等待确认)。在重试前与用户确认。"
exit 1
else
echo "❌ plannotator PLAN 门失败(代码=$PLAN_RC)"
exit 1
fi
mkdir -p .omc/plans .omc/logs
- 编写
plan.md(包括目标、步骤、风险和完成标准) - 调用 plannotator(按平台):
- Claude Code(仅支持钩子模式):
plannotator是一个仅钩子的二进制文件。不能通过 MCP 工具或 CLI 直接调用。
调用EnterPlanMode,在规划模式下编写计划内容,然后调用ExitPlanMode。
ExitPlanModePermissionRequest 钩子会自动触发 JEO Claude 计划门包装器。
该包装器必须在当前计划哈希已有最终审查结果时跳过重新进入。
等待钩子返回再继续 — 批准或反馈将通过钩子结果到达。 - Codex / Gemini / OpenCode:运行阻塞 CLI(从不使用
&):# _JEO_SCRIPTS 必须首先通过上面预检中的动态路径发现块解析 bash "${_JEO_SCRIPTS}/plannotator-plan-loop.sh" plan.md /tmp/plannotator_feedback.txt 3如果
plannotator缺失,JEO 必须首先自动运行bash "${_JEO_SCRIPTS}/ensure-plannotator.sh",并仅在 CLI 可用后继续。
- Claude Code(仅支持钩子模式):
- 检查结果:
approved: true(Claude Code:钩子返回批准)→ 更新jeo-state.json中的phase为"execute",plan_approved为true→ 进入步骤 2- 未批准(Claude Code:钩子返回反馈;其他:
exit 10)→ 读取反馈,修订plan.md→ 重复步骤 2 - 基础设施阻塞(
exit 32)→ localhost 绑定不可用(例如,沙箱/CI)。在 TTY 中使用手动门;在沙箱外与非 TTY 中确认用户并重试 - 会话退出 3 次(
exit 30/31)→ 询问用户是否结束 PLAN 并决定中止或恢复
绝不:在没有 approved: true 的情况下进入执行步骤。绝不:使用 & 后台运行。
绝不:在 approved、manual_approved、feedback_required 或 infrastructure_blocked 后重新打开相同的未更改计划。
步骤 2:执行
预检(自动检测团队可用性):
# 记录检查点
python3 -c "
import json,datetime,os,subprocess,fcntl
try:
root=subprocess.check_output(['git','rev-parse','--show-toplevel'],stderr=subprocess.DEVNULL).decode().strip()
except:
root=os.getcwd()
f=os.path.join(root,'.omc/state/jeo-state.json')
if os.path.exists(f):
with open(f,'r+') as fh:
fcntl.flock(fh,fcntl.LOCK_EX)
try:
d=json.load(fh)
d.update({'checkpoint':'execute','updated_at':datetime.datetime.utcnow().isoformat()+'Z'})
fh.seek(0); json.dump(d,fh,ensure_ascii=False,indent=2); fh.truncate()
finally:
fcntl.flock(fh,fcntl.LOCK_UN)
" 2>/dev/null || true
TEAM_AVAILABLE=false
if [[ "${CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS:-}" =~ ^(1|true|True|yes|YES)$ ]]; then
TEAM_AVAILABLE=true
elif python3 -c "
import json, os, sys
try:
s = json.load(open(os.path.expanduser('~/.claude/settings.json')))
val = s.get('env', {}).get('CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS', '')
sys.exit(0 if str(val) in ('1', 'true', 'True', 'yes') else 1)
except Exception:
sys.exit(1)
" 2>/dev/null; then
TEAM_AVAILABLE=true
fi
export TEAM_AVAILABLE_BOOL="$TEAM_AVAILABLE"
python3 -c "
import json,os,subprocess,fcntl
try:
root=subprocess.check_output(['git','rev-parse','--show-toplevel'],stderr=subprocess.DEVNULL).decode().strip()
except:
root=os.getcwd()
f=os.path.join(root,'.omc/state/jeo-state.json')
if os.path.exists(f):
with open(f,'r+') as fh:
fcntl.flock(fh,fcntl.LOCK_EX)
try:
d=json.load(fh)
d['team_available']=os.environ.get('TEAM_AVAILABLE_BOOL','false').lower()=='true'
fh.seek(0); json.dump(d,fh,ensure_ascii=False,indent=2); fh.truncate()
finally:
fcntl.flock(fh,fcntl.LOCK_UN)
" 2>/dev/null || true
- 更新
jeo-state.json中的phase为"execute" - 团队可用(Claude Code + omc):
/omc:team 3:executor "<任务>" - Claude Code 但没有团队:
echo "❌ JEO 需要 Claude Code 团队模式。重新运行 bash scripts/setup-claude.sh,重启 Claude Code,并确认 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1。" exit 1绝不在 Claude Code 中回退到单代理执行。
- 无 omc(BMAD 回退 — 仅 Codex / Gemini / OpenCode):
/workflow-init # 初始化 BMAD /workflow-status # 检查当前步骤
步骤 3:验证
- 更新
jeo-state.json中的phase为"verify" - 使用 agent-browser 进行基本验证(当存在浏览器 UI 时):
agent-browser snapshot http://localhost:3000 - 检测到
annotate关键词 → 进入步骤 3.1 - 否则 → 进入步骤 4
步骤 3.1:验证 UI(仅在检测到 annotate 关键词时)
- 预检检查(进入前必需):
# 自动启动服务器,自动安装包,自动注入组件(完整脚本见 §3.3.1) bash scripts/ensure-agentation.sh --project-dir "${PROJECT_DIR:-$PWD}" --endpoint "http://localhost:4747" || true # 如果预检后 agentation-mcp 服务器仍然不健康 → 优雅跳过至步骤 4 if ! curl -sf --connect-timeout 2 http://localhost:4747/health >/dev/null 2>&1; then python3 -c "
import json,os,subprocess,fcntl,time
try:
root=subprocess.check_output([‘git’,’rev-parse’,’–show-toplevel’],stderr=subprocess.DEVNULL).decode().strip()
except:
root=os.getcwd()
f=os.path.join(root,’.omc/state/jeo-state.json’)
if os.path.exists(f):
with open(f,’r+’) as fh:
fcntl.flock(fh,fcntl.LOCK_EX)
try:
d=json.load(fh)
d[‘last_error’]=’agentation-mcp not running; VERIFY_UI skipped’
d[‘updated_at’]=time.strftime(‘%Y-%m-%dT%H:%M:%SZ’,time.gmtime())
fh.seek(0); json.dump(d,fh,ensure_ascii=False,indent=2); fh.truncate()
finally:
fcntl.flock(fh,fcntl.LOCK_UN)
” 2>/dev/null || true
# 继续到步骤 4 清理(不 exit 1 — 优雅跳过)
fi
2. 更新 `jeo-state.json`:`phase = "verify_ui"`,`agentation.active = true`,`agentation.submit_gate_status = "waiting_for_submit"`
3. 等待明确的人类提交:
- **Claude Code**:在用户按下**发送注释** / `onSubmit` 后等待 `UserPromptSubmit`
- **Codex / Gemini / OpenCode**:等待人类确认提交且代理发出 `ANNOTATE_READY`(或兼容别名 `AGENTUI_READY`)
4. 在提交信号到达之前,不要读取 `/pending`,不要确认注释,也不要开始修复循环
5. 提交到达后,将 `agentation.submit_gate_status` 切换为 `"submitted"`,并记录 `submit_signal`、`submit_received_at` 和 `submitted_annotation_count`
6. **Claude Code (MCP)**:阻塞调用 `agentation_watch_annotations` (`batchWindowSeconds:10`,`timeoutSeconds:120`)
7. **Codex / Gemini / OpenCode (HTTP)**:通过 `GET http://localhost:4747/pending` 进行轮询循环
8. 处理每个注释:`acknowledge` → 通过 `elementPath` 导航代码 → 应用修复 → `resolve`
9. `count=0` 或超时 → 重置提交门或完成子阶段 → **进入步骤 4**
**绝不:在 submit/onSubmit 之前处理草稿注释。**
---
### 步骤 4:清理
**预检(进入前检查):**
```bash
# 记录检查点
python3 -c "
import json,datetime,os,subprocess,fcntl
try:
root=subprocess.check_output(['git','rev-parse','--show-toplevel'],stderr=subprocess.DEVNULL).decode().strip()
except:
root=os.getcwd()
f=os.path.join(root,'.omc/state/jeo-state.json')
if os.path.exists(f):
with open(f,'r+') as fh:
fcntl.flock(fh,fcntl.LOCK_EX)
try:
d=json.load(fh)
d.update({'checkpoint':'cleanup','updated_at':datetime.datetime.utcnow().isoformat()+'Z'})
fh.seek(0); json.dump(d,fh,ensure_ascii=False,indent=2); fh.truncate()
finally:
fcntl.flock(fh,fcntl.LOCK_UN)
" 2>/dev/null || true
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "⚠️ 不是 git 仓库 — 跳过工作树清理"
else
UNCOMMITTED=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
[[ "$UNCOMMITTED" -gt 0 ]] && echo "⚠️ ${UNCOMMITTED} 个未提交的更改 — 建议在清理前提交/暂存"
fi
- 更新
jeo-state.json中的phase为"cleanup" - 工作树清理:
bash scripts/worktree-cleanup.sh || git worktree prune - 更新
jeo-state.json中的phase为"done"
1. 快速开始
真实来源:
https://github.com/supercent-io/skills-template
像~/.claude/skills/jeo/这样的本地路径是通过npx skills add安装的副本。
要更新到最新版本,请使用下面的命令重新安装。
# 安装 JEO(npx skills add — 推荐)
npx skills add https://github.com/supercent-io/skills-template --skill jeo
# 完整安装(所有 AI 工具 + 所有组件)
bash scripts/install.sh --all
# 检查状态
bash scripts/check-status.sh
# 单个 AI 工具设置
bash scripts/setup-claude.sh # Claude Code 插件 + 钩子
bash scripts/setup-codex.sh # Codex CLI developer_instructions
bash scripts/setup-gemini.sh # Gemini CLI 钩子 + GEMINI.md
bash scripts/setup-opencode.sh # OpenCode 插件注册
2. 已安装组件
JEO 安装和配置的工具:
| 工具 | 描述 | 安装命令 |
|---|---|---|
| omc (oh-my-claudecode) | Claude Code 多代理编排 | /plugin marketplace add https://github.com/Yeachan-Heo/oh-my-claudecode |
| omx | OpenCode 的多代理编排 | bunx oh-my-opencode setup |
| ohmg | Gemini CLI 的多代理框架 | bunx oh-my-ag |
| bmad | BMAD 工作流编排 | 包含在技能中 |
| ralph | 自我引用完成循环 | 包含在 omc 中或单独安装 |
| plannotator | 可视化计划/差异审查 | 在 PLAN 期间通过 bash scripts/ensure-plannotator.sh 自动安装(或使用 bash scripts/install.sh --with-plannotator 预安装) |
| agentation | UI 注释 → 代理代码修复集成(annotate 关键词,保持 agentui 兼容性) |
bash scripts/install.sh --with-agentation |
| agent-browser | 用于 AI 代理的无头浏览器 — 浏览器行为验证的主要工具 | npm install -g agent-browser |
| playwriter | 基于 Playwright 的浏览器自动化(可选) | npm install -g playwriter |
3. JEO 工作流
完整流程
jeo "<任务>"
│
▼
[1] 规划 (ralph + plannotator)
使用 ralph 起草计划 → 使用 plannotator 进行可视化审查 → 批准/反馈
│
▼
[2] 执行
├─ 团队可用? → /omc:team N:executor "<任务>"
│ 阶段式流水线:计划→产品需求文档→执行→验证→修复
└─ 无团队? → /bmad /workflow-init → 运行 BMAD 步骤
│
▼
[3] 验证 (agent-browser — 默认行为)
使用 agent-browser 验证浏览器行为
→ 捕获快照 → 确认 UI/功能正常工作
│
├─ 带有 annotate 关键词 → [3.3.1] 验证 UI (agentation 监视循环)
│ agentation_watch_annotations 阻塞 → 注释确认→修复→解决循环
│
▼
[4] 清理
所有工作完成后 → bash scripts/worktree-cleanup.sh
git worktree prune
3.1 规划步骤 (ralph + plannotator)
平台说明:
/ralph斜杠命令仅在 Claude Code (omc) 中可用。
对于 Codex/Gemini/OpenCode,请使用下面的“替代方法”。
Claude Code (omc):
/ralph "jeo-plan: <任务>" --completion-promise="PLAN_APPROVED" --max-iterations=5
Codex / Gemini / OpenCode(替代方法):
# 会话隔离的反馈目录(防止并发运行冲突)
FEEDBACK_DIR=$(python3 -c "import hashlib,os; h=hashlib.md5(os.getcwd().encode()).hexdigest()[:8]; d=f'/tmp/jeo-{h}'; os.makedirs(d,exist_ok=True); print(d)" 2>/dev/null || echo '/tmp')
FEEDBACK_FILE="${FEEDBACK_DIR}/plannotator_feedback.txt"
# 1. 直接编写 plan.md,然后用 plannotator 审查(阻塞 — 无 &)
PLANNOTATOR_RUNTIME_HOME="${FEEDBACK_DIR}/.plannotator"
mkdir -p "$PLANNOTATOR_RUNTIME_HOME"
touch /tmp/jeo-plannotator-direct.lock && python3 -c "
import json
print(json.dumps({'tool_input': {'plan': open('plan.md').read(), 'permission_mode': 'acceptEdits'}}))
" | env HOME="$PLANNOTATOR_RUNTIME_HOME" PLANNOTATOR_HOME="$PLANNOTATOR_RUNTIME_HOME" plannotator > "$FEEDBACK_FILE" 2>&1
# ↑ 不加 & 运行:等待用户在浏览器中点击批准/发送反馈
# 2. 检查结果并分支
if python3 -c "
import json, sys
try:
d = json.load(open('$FEEDBACK_FILE'))
sys.exit(0 if d.get('approved') is True else 1)
except Exception:
sys.exit(1)
" 2>/dev/null; then
echo "PLAN_APPROVED" # → 进入执行步骤
else
echo "PLAN_FEEDBACK" # → 读取 \"$FEEDBACK_FILE\",重新计划,重复上述过程
fi
重要:不要使用
&(后台)运行。必须阻塞运行才能接收用户反馈。
常见流程:
- 生成计划文档 (
plan.md) - 阻塞运行 plannotator → 浏览器 UI 自动打开
- 在浏览器中审查计划 → 批准或发送反馈
- 批准 (
"approved":true) → 进入 [2] 执行步骤 - 反馈 → 读取
/tmp/plannotator_feedback.txt注释并重新计划(循环) - exit 32(沙箱/CI — 对话批准模式):
- 向用户输出完整的
plan.md内容 - 询问:”⚠️ plannotator UI 不可用。回复 ‘approve’ 继续或提供反馈。”
- 等待用户响应 — 不要进入执行步骤
- 批准时 → 更新
jeo-state.json中plan_approved=true,plan_gate_status="manual_approved"→ 执行 - 反馈时 → 修订
plan.md,重试循环,重复
- 向用户输出完整的
Claude Code 手动运行:
Shift+Tab×2 → 进入计划模式 → 计划完成时 plannotator 自动运行
3.2 执行步骤
当团队可用时(Claude Code + omc):
/omc:team 3:executor "jeo-exec: <基于已批准计划的任务>"
- 阶段式流水线:团队规划 → 团队产品需求文档 → 团队执行 → 团队验证 → 团队修复
- 通过并行代理执行最大化速度
当 Claude Code 团队模式不可用时:
echo "❌ JEO 在 Claude Code 中需要 /omc:team。运行 bash scripts/setup-claude.sh,重启 Claude Code,然后重试。"
exit 1
- 不要降级到单代理模式
当团队不可用时(BMAD 回退 — Codex / Gemini / OpenCode):
/workflow-init # 初始化 BMAD 工作流
/workflow-status # 检查当前步骤
- 按顺序进行:分析 → 规划 → 方案设计 → 实现
- 每个步骤完成后使用 plannotator 审查文档
3.3 验证步骤 (agent-browser — 默认行为)
当存在基于浏览器的功能时,使用 agent-browser 验证行为。
# 从应用运行的 URL 捕获快照
agent-browser snapshot http://localhost:3000
# 检查特定元素(可访问性树引用方法)
agent-browser snapshot http://localhost:3000 -i
# → 使用 @eN 引用号检查元素状态
# 保存截图
agent-browser screenshot http://localhost:3000 -o verify.png
默认行为:当与浏览器相关的工作完成时,自动运行 agent-browser 验证步骤。
没有浏览器 UI 的后端/CLI 任务会跳过此步骤。
3.3.1 验证 UI 步骤 (annotate — agentation 监视循环)
当检测到 annotate 关键词时,运行 agentation 监视循环。(agentui 关键词也受支持,以保持向后兼容性。)
这遵循与 plannotator 在 planui / ExitPlanMode 中相同的模式。
先决条件(由预检自动解析):
npx agentation-mcp server(HTTP :4747) 正在运行 — 如果未运行,则自动启动agentationnpm 包已安装在项目中 — 如果缺失,则自动安装<Agentation endpoint="http://localhost:4747" />已挂载在应用中 — 如果缺失,则自动注入到入口点
预检检查(进入前必需 — 所有平台通用):
# ── 步骤 1:如果未运行,自动启动 agentation-mcp 服务器 ─────────────────
JEO_AGENTATION_ENDPOINT="${JEO_AGENTATION_ENDPOINT:-http://localhost:4747}"
JEO_AGENTATION_PORT="${JEO_AGENTATION_PORT:-4747}"
if ! curl -sf --connect-timeout 2 "${JEO_AGENTATION_ENDPOINT}/health" >/dev/null 2>&1; then
echo "[JEO][ANNOTATE] agentation-mcp 未运行 — 尝试在端口 ${JEO_AGENTATION_PORT} 上自动启动..."
if command -v npx >/dev/null 2>&1; then
npx -y agentation-mcp server --port "${JEO_AGENTATION_PORT}" >/tmp/agentation-mcp.log 2>&1 &
AGENTATION_MCP_PID=$!
echo "[JEO][ANNOTATE] 已启动 agentation-mcp (PID ${AGENTATION_MCP_PID})"
# 等待最多 8 秒让服务器变得健康
for i in $(seq 1 8); do
sleep 1
if curl -sf --connect-timeout 1 "${JEO_AGENTATION_ENDPOINT}/health" >/dev/null 2>&1; then
echo "[JEO][ANNOTATE] ✅ agentation-mcp 服务器已就绪"
break
fi
done
if ! curl -sf --connect-timeout 2 "${JEO_AGENTATION_ENDPOINT}/health" >/dev/null 2>&1; then
echo "[JEO][ANNOTATE] ⚠️ agentation-mcp 启动失败 — 跳过 VERIFY_UI"
python3 -c "
import json,os,subprocess,fcntl,time
try:
root=subprocess.check_output(['git','rev-parse','--show-toplevel'],stderr=subprocess.DEVNULL).decode().strip()
except:
root=os.getcwd()
f=os.path.join(root,'.omc/state/jeo-state.json')
if os.path.exists(f):
with open(f,'r+') as fh:
fcntl.flock(fh,fcntl.LOCK_EX)
try:
d=json.load(fh)
d['last_error']='agentation-mcp failed to start; VERIFY_UI skipped'
d['updated_at']=time.strftime('%Y-%m-%dT%H:%M:%SZ',time.gmtime())
fh.seek(0); json.dump(d,fh,ensure_ascii=False,indent=2); fh.truncate()
finally:
fcntl.flock(fh,fcntl.LOCK_UN)
" 2>/dev/null || true
# 继续到步骤 4 清理(不 exit 1 — 优雅跳过)
fi
else
echo "[JEO][ANNOTATE] ⚠️ npx 未找到 — 无法自动启动 agentation-mcp。跳过 VERIFY_UI。"
python3 -c "
import json,os,subprocess,fcntl,time
try:
root=subprocess.check_output(['git','rev-parse','--show-toplevel'],stderr=subprocess.DEVNULL).decode().strip()
except:
root=os.getcwd()
f=os.path.join(root,'.omc/state/jeo-state.json')
if os.path.exists(f):
with open(f,'r+') as fh:
fcntl.flock(fh,fcntl.LOCK_EX)
try:
d=json.load(fh)
d['last_error']='npx not found; agentation-mcp auto-start skipped; VERIFY_UI skipped'
d['updated_at']=time.strftime('%Y-%m-%dT%H:%M:%SZ',time.gmtime())
fh.seek(0); json.dump(d,fh,ensure_ascii=False,indent=2); fh.truncate()
finally:
fcntl.flock(fh,fcntl.LOCK_UN)
" 2>/dev/null || true
# 继续到步骤 4 清理(不 exit 1 — 优雅跳过)
fi
fi
# ── 步骤 2:如果需要,自动安装 agentation 包 + 注入 <Agentation> ──
# 仅在确认服务器健康后运行
if curl -sf --connect-timeout 2 "${JEO_AGENTATION_ENDPOINT}/health" >/dev/null 2>&1; then
SESSIONS=$(curl -sf "${JEO_AGENTATION_ENDPOINT}/sessions" 2>/dev/null || echo "[]")
S_COUNT=$(echo "$SESSIONS" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null || echo 0)
if [ "$S_COUNT" -eq 0 ]; then
echo "[JEO][ANNOTATE] 无活跃会话 — 运行 ensure-agentation.sh 以安装包并注入组件..."
# 定位 ensure-agentation.sh(尝试常见的安装路径)
ENSURE_SCRIPT=""
for candidate in \
"$(dirname "${BASH_SOURCE[0]:-$0}")/ensure-agentation.sh" \
"$HOME/.claude/skills/jeo/scripts/ensure-agentation.sh" \
"$HOME/.agent-skills/jeo/scripts/ensure-agentation.sh" \
"$HOME/.codex/skills/jeo/scripts/ensure-agentation.sh"; do
if [[ -f "$candidate" ]]; then
ENSURE_SCRIPT="$candidate"
break
fi
done
if [[ -n "$ENSURE_SCRIPT" ]]; then
ENSURE_EXIT=0
bash "$ENSURE_SCRIPT" \
--project-dir "${PROJECT_DIR:-$PWD}" \
--endpoint "${JEO_AGENTATION_ENDPOINT}" || ENSURE_EXIT=$?
if [ "$ENSURE_EXIT" -eq 0 ]; then
echo "[JEO][ANNOTATE] ensure-agentation 完成 — 等待最多 15 秒让浏览器重新连接..."
# 等待开发服务器热重载和浏览器重新连接
for i in $(seq 1 15); do
sleep 1
NEW_S_COUNT=$(curl -sf "${JEO_AGENTATION_ENDPOINT}/sessions" 2>/dev/null | \
python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null || echo 0)
if [ "$NEW_S_COUNT" -gt 0 ]; then
echo "[JEO][ANNOTATE] ✅ 浏览器会话已建立 (${NEW_S_COUNT} 个会话)"
S_COUNT=$NEW_S_COUNT
break
fi
done
if [ "$S_COUNT" -eq 0 ]; then
echo "[JEO][ANNOTATE] ⚠️ 组件已注入但尚无浏览器会话。"
echo " → 刷新浏览器中的应用 URL,then 重新运行 annotate。"
fi
elif [ "$ENSURE_EXIT" -eq 2 ]; then
echo "[JEO][ANNOTATE] ℹ️ 不是 Node.js 项目 — 请手动挂载 <Agentation endpoint='${JEO_AGENTATION_ENDPOINT}' />。"
else
echo "[JEO][ANNOTATE] ⚠️ ensure-agentation.sh 失败 (退出码 $ENSURE_EXIT) — 请手动挂载 <Agentation endpoint='${JEO_AGENTATION_ENDPOINT}' />。"
fi
else
echo "[JEO][ANNOTATE] ⚠️ 未找到 ensure-agentation.sh — 请手动挂载 <Agentation endpoint='${JEO_AGENTATION_ENDPOINT}' />。"
fi
fi
echo "[JEO][ANNOTATE] ✅ agentation 已就绪 — 服务器 OK,${S_COUNT} 个会话"
fi
通过预检后(
else分支),更新 jeo-state.json 中的phase为"verify_ui",设置agentation.active为true,并设置agentation.submit_gate_status为"waiting_for_submit"。
在用户明确提交之前,不要调用/pending。草稿注释在用户明确提交之前是不可操作的。
Claude Code(直接 MCP 工具调用):
# 检测到 annotate 关键词(或 agentui — 向后兼容)
# 1. 在用户点击发送注释 / onSubmit 后等待 UserPromptSubmit
# 2. JEO 提交门钩子记录 submit_gate_status="submitted"
# 3. 然后才运行阻塞的 agentation 监视循环
#
# batchWindowSeconds:10 — 每 10 秒批量接收注释
# timeoutSeconds:120 — 120 秒无注释后自动退出
#
# 每个注释的处理循环:
# 1. agentation_acknowledge_annotation({id}) — 在 UI 中显示“处理中”
# 2. 通过 annotation.elementPath (CSS 选择器) 导航代码 → 应用修复
# 3. agentation_resolve_annotation({id, summary}) — 标记为“已完成”并保存摘要
#
# 当注释计数 = 0 或超时时循环结束
重要:
agentation_watch_annotations是一个阻塞调用。不要使用&后台运行。
与 plannotator 的approved:true循环相同:注释计数 = 0 或超时 = 完成信号。
annotate是主要关键词。agentui是一个向后兼容的别名,行为相同。
Codex / Gemini / OpenCode(HTTP REST API 回退):
START_TIME=$(date +%s)
TIMEOUT_SECONDS=120
# 必需的门:在人类点击发送注释且平台打开 agentation.submit_gate_status="submitted" 之前,不要进入循环
while true; do
# 超时检查
NOW=$(date +%s)
ELAPSED=$((NOW - START_TIME))
if [ $ELAPSED -ge $TIMEOUT_SECONDS ]; then
echo "[JEO] agentation 轮询超时(${TIMEOUT_SECONDS}秒)— 某些注释可能仍未解决"
break
fi
SUBMIT_GATE=$(python3 -c "
import json
try:
print(json.load(open('.omc/state/jeo-state.json')).get('agentation', {}).get('submit_gate_status', 'idle'))
except Exception:
print('idle')
" 2>/dev/null || echo "idle")
if [ "$SUBMIT_GATE" != "submitted" ]; then
sleep 2
continue
fi
COUNT=$(curl -sf --connect-timeout 3 --max-time 5 http://localhost:4747/pending 2>/dev/null | python3 -c "import sys,json; data=sys.stdin.read(); d=json.loads(data) if data.strip() else {}; print(d.get('count', len(d.get('annotations', [])) if isinstance(d, dict) else 0))" 2>/dev/null || echo 0)
[ "$COUNT" -eq 0 ] && break
# 处理每个注释:
# a) 确认(显示为进行中)
curl -X PATCH http://localhost:4747/annotations/<id> \
-H 'Content-Type: application/json' \
-d '{"status": "acknowledged"}'
# b) 通过 elementPath (CSS 选择器) 导航代码 → 应用修复
# c) 解决(标记完成 + 修复摘要)
curl -X PATCH http://localhost:4747/annotations/<id> \
-H 'Content-Type: application/json' \
-d '{"status": "resolved", "resolution": "<修复摘要>"}'
sleep 3
done
3.4 清理步骤(自动工作树清理)
# 所有工作完成后自动运行
bash scripts/worktree-cleanup.sh
# 单个命令
git worktree list # 列出当前工作树
git worktree prune # 清理已删除分支的工作树
bash scripts/worktree-cleanup.sh --force # 强制清理,包括脏工作树
默认运行仅移除干净的额外工作树;有更改的工作树会留下并发出警告。
仅在审查后使用--force。
4. 平台插件配置
4.1 Claude Code
# 自动设置
bash scripts/setup-claude.sh
# 或手动:
/plugin marketplace add https://github.com/Yeachan-Heo/oh-my-claudecode
/plugin install oh-my-claudecode
/omc:omc-setup
# 添加 plannotator 钩子
bash .agent-skills/plannotator/scripts/setup-hook.sh
配置文件:~/.claude/settings.json
{
"hooks": {
"PermissionRequest": [{
"matcher": "ExitPlanMode",
"hooks": [{
"type": "command",
"command": "python3 ~/.claude/skills/jeo/scripts/claude-plan-gate.py",
"timeout": 1800
}]
}]
}
}
agentation MCP 配置(~/.claude/settings.json 或 .claude/mcp.json):
{
"mcpServers": {
"agentation": {
"command": "npx",
"args": ["-y", "agentation-mcp", "server"]
}
},
"hooks": {
"UserPromptSubmit": [{
"matcher": "*",
"hooks": [{
"type": "command",
"command": "python3 ~/.claude/skills/jeo/scripts/claude-agentation-submit-hook.py",
"timeout": 300
}]
}]
}
}
4.2 Codex CLI
# 自动设置
bash scripts/setup-codex.sh
# 配置的内容:
# - developer_instructions: ~/.codex/config.toml
# - 提示文件: ~/.codex/prompts/jeo.md
# - 通知钩子: ~/.codex/hooks/jeo-notify.py
# - [tui] notifications: agent-turn-complete
agentation MCP 配置(~/.codex/config.toml):
[mcp_servers.agentation]
command = "npx"
args = ["-y", "agentation-mcp", "server"]
通知钩子(~/.codex/hooks/jeo-notify.py):
- 在代理回合完成时,检测
last-assistant-message中的PLAN_READY信号 - 确认
plan.md存在,将当前哈希与last_reviewed_plan_hash比较,并在计划已被审查时跳过门 - 将结果保存到
/tmp/plannotator_feedback.txt - 仅在
verify_ui中检测ANNOTATE_READY信号(或向后兼容的AGENTUI_READY) - 首先打开
agentation.submit_gate_status="submitted",然后轮询http://localhost:4747/pending
~/.codex/config.toml 配置:
developer_instructions = """
# JEO 编排工作流
# ...
"""
notify = ["python3", "~/.codex/hooks/jeo-notify.py"]
[tui]
notifications = ["agent-turn-complete"]
notification_method = "osc9"
developer_instructions必须是一个顶级字符串。
将其写为[developer_instructions]表可能会导致 Codex 启动时失败,出现invalid type: map, expected a string。
notify和[tui].notifications也必须正确设置,才能使 PLAN/ANNOTATE 后续循环正常工作。
在 Codex 中使用:
/prompts:jeo # 激活 JEO 工作流
# 代理编写 plan.md 并输出 "PLAN_READY" → 通知钩子自动运行
4.3 Gemini CLI
# 自动设置
bash scripts/setup-gemini.sh
# 配置的内容:
# - AfterAgent 备份钩子: ~/.gemini/hooks/jeo-plannotator.sh
# - 指令(强制循环):~/.gemini/GEMINI.md
关键原则:代理必须直接以阻塞模式调用 plannotator,以在同一回合中接收反馈。
AfterAgent 钩子仅作为安全网(在回合结束后运行 → 在下一回合中注入)。
AfterAgent 备份钩子(~/.gemini/settings.json):
{
"hooks": {
"AfterAgent": [{
"matcher": "",
"hooks": [{
"name": "plannotator-review",
"type": "command",
"command": "bash ~/.gemini/hooks/jeo-plannotator.sh",
"description": "当检测到 plan.md 时运行 plannotator(AfterAgent 备份)"
}]
}]
}
}
添加到 GEMINI.md 的 PLAN 指令(强制循环):
1. 编写 plan.md
2. 阻塞运行 plannotator(无 &)→ /tmp/plannotator_feedback.txt
3. approved=true → 执行 / 未批准 → 修订并重复步骤 2
在没有 approved=true 的情况下,绝不进入执行步骤。
agentation MCP 配置(~/.gemini/settings.json):
{
"mcpServers": {
"agentation": {
"command": "npx",
"args": ["-y", "agentation-mcp", "server"]
}
}
}
注意:Gemini CLI 钩子事件使用
BeforeTool和AfterAgent。
ExitPlanMode是仅限 Claude Code 的钩子。
4.4 OpenCode
# 自动设置
bash scripts/setup-opencode.sh
# 添加到 opencode.json 的内容:
# "@plannotator/opencode@latest" 插件
# "@oh-my-opencode/opencode@latest" 插件 (omx)
OpenCode 斜杠命令:
/jeo-plan— 使用 ralph + plannotator 进行规划/jeo-exec— 使用团队/bmad 执行/jeo-annotate— 启动 agentation 监视循环(annotate;/jeo-agentui是已弃用的别名)/jeo-cleanup— 工作树清理
plannotator 集成(强制阻塞循环):
# 编写 plan.md 然后运行 PLAN 门(无 &)— 在同一回合中接收反馈
bash scripts/plannotator-plan-loop.sh plan.md /tmp/plannotator_feedback.txt 3
# - 必须等待直到收到批准/反馈
# - 会话退出时自动重启(最多 3 次)
# - 3 次退出后,与用户确认是中止还是恢复
# - 如果 localhost 绑定不可用,则退出 32(替换为 TTY 中的手动门)
# 根据结果分支
# approved=true → 进入执行
# not approved → 应用反馈,修订 plan.md → 重复上述
agentation MCP 配置(opencode.json):
{
"mcp": {
"agentation": {
"type": "local",
"command": ["npx", "-y", "agentation-mcp", "server"]
}
}
}
5. 内存与状态
JEO 在以下路径存储状态:
{工作树}/.omc/state/jeo-state.json # JEO 执行状态
{工作树}/.omc/plans/jeo-plan.md # 已批准的计划
{工作树}/.omc/logs/jeo-*.log # 执行日志
状态文件结构:
{
"mode": "jeo",
"phase": "plan|execute|verify|verify_ui|cleanup|done",
"session_id": "<uuid>",
"task": "当前任务描述",
"plan_approved": true,
"plan_gate_status": "pending|approved|feedback_required|infrastructure_blocked|manual_approved",
"plan_current_hash": "<sha256 or null>",
"last_reviewed_plan_hash": "<sha256 or null>",
"last_reviewed_plan_at": "2026-02-24T00:00:00Z",
"plan_review_method": "plannotator|manual|null",
"team_available": true,
"retry_count": 0,
"last_error": null,
"checkpoint": "plan|execute|verify|verify_ui|cleanup",
"created_at": "2026-02-24T00:00:00Z",
"updated_at": "2026-02-24T00:00:00Z",
"agentation": {
"active": false,
"session_id": null,
"keyword_used": null,
"submit_gate_status": "idle|waiting_for_submit|submitted",
"submit_signal": "claude-user-prompt-submit|codex-notify|gemini-manual|null",
"submit_received_at": "2026-02-24T00:00:00Z",
"submitted_annotation_count": 0,
"started_at": null,
"timeout_seconds": 120,
"annotations": {
"total": 0, "acknowledged": 0, "resolved": 0, "dismissed": 0, "pending": 0
},
"completed_at": null,
"exit_reason": null
}
}
agentation 字段:
active— 监视循环是否正在运行(用作钩子保护),session_id— 用于恢复,
submit_gate_status— 防止在提交/onSubmit 之前处理草稿注释,submit_signal— 哪个平台打开了门,
submit_received_at/submitted_annotation_count— 提交批次的审计跟踪,exit_reason—"all_resolved"|"timeout"|"user_cancelled"|"error"已忽略的注释:当用户在 agentation UI 中忽略一个注释时(状态变为
"dismissed"),
代理应该跳过该注释的代码更改,递增annotations.dismissed,并继续处理下一个待处理注释。
已忽略的注释会计数但不执行操作。当pending == 0时(已解决 + 已忽略覆盖所有注释),监视循环正常退出。
plan_review_method:通过 UI 批准时设置为"plannotator",通过 TTY 回退门批准时设置为"manual"。
cleanup_completed:由worktree-cleanup.sh在成功进行工作树修剪后设置为true。
错误恢复字段:
retry_count— 出错后的重试次数。每次预检失败时递增 +1。如果>= 3,询问用户确认。last_error— 最近的错误消息。用于在重启时识别原因。checkpoint— 最后启动的阶段。重启时从此阶段恢复 (plan|execute|verify|cleanup)。
基于检查点的恢复流程:
# 重启时检查检查点
python3 -c "
import json, os, subprocess
try:
root = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'], stderr=subprocess.DEVNULL).decode().strip()
except:
root = os.getcwd()
f = os.path.join(root, '.omc/state/jeo-state.json')
if os.path.exists(f):
d=json.load(open(f))
cp=d.get('checkpoint')
err=d.get('last_error')
rc=d.get('retry_count',0)
print(f'从以下阶段恢复:{cp or \"开始\"}')
if err: print(f'之前的错误({rc} 次):{err}')
if rc >= 3: print('⚠️ 重试次数超过 3 次 — 需要用户确认')
"
重启后恢复:
# 检查状态并恢复
bash scripts/check-status.sh --resume
6. 推荐工作流
# 步骤 1:安装(一次)
bash scripts/install.sh --all
bash scripts/check-status.sh
# 步骤 2:开始工作
jeo "<任务描述>" # 使用关键词激活
# 或在 Claude 中:Shift+Tab×2 → 进入计划模式
# 步骤 3:使用 plannotator 审查计划
# 在浏览器 UI 中批准或发送反馈
# 步骤 4:自动执行
# 团队或 bmad 处理工作
# 步骤 5:完成后清理
bash scripts/worktree-cleanup.sh
7. 最佳实践
- 计划先行:在执行前始终使用 ralph+plannotator 审查计划(及早发现错误方法)
- 团队优先:在 Claude Code 中,omc 团队模式效率最高
- bmad 回退:在没有团队的环境中使用 BMAD(Codex、Gemini)
- 工作树清理:工作完成后立即运行
worktree-cleanup.sh(防止分支污染) - 状态持久性:使用
.omc/state/jeo-state.json在会话间保持状态 - annotate:对于复杂的 UI 更改,使用
annotate关键词运行 agentation 监视循环(通过 CSS 选择器进行精确的代码更改)。agentui是一个向后兼容的别名。
8. 故障排除
| 问题 | 解决方案 |
|---|---|
| plannotator 未运行 | JEO 首先自动运行 bash scripts/ensure-plannotator.sh;如果仍然失败,运行 bash .agent-skills/plannotator/scripts/check-status.sh |
| plannotator 在 Claude Code 中未打开 | plannotator 是仅钩子的。不要通过 MCP 或 CLI 调用它。使用 EnterPlanMode → 编写计划 → ExitPlanMode;钩子会自动触发。验证钩子是否设置:cat ~/.claude/settings.json | python3 -c "import sys,json;h=json.load(sys.stdin).get('hooks',{});print(h.get('PermissionRequest','missing'))" |
| 未收到 plannotator 反馈 | 移除 & 后台执行 → 阻塞运行,然后检查 /tmp/plannotator_feedback.txt(仅限 Codex/Gemini/OpenCode) |
| 相同计划在 Codex 中被重复审查 | 将 jeo-state.json 中的 last_reviewed_plan_hash 与当前 plan.md 哈希进行比较。如果它们匹配且 plan_gate_status 是最终的,则不要重新运行 |
Codex 启动失败(invalid type: map, expected a string) |
重新运行 bash scripts/setup-codex.sh,并确认 ~/.codex/config.toml 中的 developer_instructions 是一个顶级字符串 |
| Gemini 反馈循环缺失 | 将阻塞直接调用指令添加到 ~/.gemini/GEMINI.md |
| 工作树冲突 | git worktree prune && git worktree list |
| 团队模式不工作 | JEO 在 Claude Code 中需要团队模式。运行 bash scripts/setup-claude.sh,重启 Claude Code,并在重试前验证 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 |
| omc 安装失败 | 运行 /omc:omc-doctor |
| agent-browser 错误 | 检查 agent-browser --version |
| annotate (agentation) 未打开 | 检查 curl http://localhost:4747/health 和 curl http://localhost:4747/sessions。JEO 在轮询 /pending 之前会等待明确的提交/onSubmit |
| 注释未反映在代码中 | 确认在调用 agentation_resolve_annotation 时存在 summary 字段 |
agentui 关键词未激活 |
使用 annotate 关键词(新)。agentui 是一个已弃用的别名,但仍然有效。 |
| MCP 工具未注册 (Codex/Gemini) | 重新运行 bash scripts/setup-codex.sh / setup-gemini.sh |
9. 参考链接
- oh-my-claudecode — Claude Code 多代理
- plannotator — 可视化计划/差异审查
- BMAD 方法 — 结构化 AI 开发工作流
- Agent Skills 规范 — 技能格式规范
- agentation — UI 注释 → 代理代码修复集成(
annotate;agentui向后兼容)
📄 原始文档
完整文档(英文):
https://skills.sh/supercent-io/skills-template/jeo
💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。

评论(0)