🚀 快速安装

复制以下命令并运行,立即安装此 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、Codex config.toml、Gemini settings.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
  1. 编写 plan.md(包括目标、步骤、风险和完成标准)
  2. 调用 plannotator(按平台):
    • Claude Code(仅支持钩子模式)
      plannotator 是一个仅钩子的二进制文件。不能通过 MCP 工具或 CLI 直接调用。
      调用 EnterPlanMode,在规划模式下编写计划内容,然后调用 ExitPlanMode
      ExitPlanMode PermissionRequest 钩子会自动触发 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 可用后继续。

  3. 检查结果:
    • approved: true(Claude Code:钩子返回批准)→ 更新 jeo-state.json 中的 phase"execute"plan_approvedtrue进入步骤 2
    • 未批准(Claude Code:钩子返回反馈;其他:exit 10)→ 读取反馈,修订 plan.md → 重复步骤 2
    • 基础设施阻塞(exit 32)→ localhost 绑定不可用(例如,沙箱/CI)。在 TTY 中使用手动门;在沙箱外与非 TTY 中确认用户并重试
    • 会话退出 3 次(exit 30/31)→ 询问用户是否结束 PLAN 并决定中止或恢复

绝不:在没有 approved: true 的情况下进入执行步骤。绝不:使用 & 后台运行。
绝不:在 approvedmanual_approvedfeedback_requiredinfrastructure_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
  1. 更新 jeo-state.json 中的 phase"execute"
  2. 团队可用(Claude Code + omc)
    /omc:team 3:executor "<任务>"
    
  3. Claude Code 但没有团队
    echo "❌ JEO 需要 Claude Code 团队模式。重新运行 bash scripts/setup-claude.sh,重启 Claude Code,并确认 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1。"
    exit 1
    

    绝不在 Claude Code 中回退到单代理执行。

  4. 无 omc(BMAD 回退 — 仅 Codex / Gemini / OpenCode)
    /workflow-init   # 初始化 BMAD
    /workflow-status # 检查当前步骤
    

步骤 3:验证

  1. 更新 jeo-state.json 中的 phase"verify"
  2. 使用 agent-browser 进行基本验证(当存在浏览器 UI 时):
    agent-browser snapshot http://localhost:3000
    
  3. 检测到 annotate 关键词 → 进入步骤 3.1
  4. 否则 → 进入步骤 4

步骤 3.1:验证 UI(仅在检测到 annotate 关键词时)

  1. 预检检查(进入前必需):
    # 自动启动服务器,自动安装包,自动注入组件(完整脚本见 §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
  1. 更新 jeo-state.json 中的 phase"cleanup"
  2. 工作树清理:
    bash scripts/worktree-cleanup.sh || git worktree prune
    
  3. 更新 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 — 对话批准模式)
    1. 向用户输出完整的 plan.md 内容
    2. 询问:”⚠️ plannotator UI 不可用。回复 ‘approve’ 继续或提供反馈。”
    3. 等待用户响应 — 不要进入执行步骤
    4. 批准时 → 更新 jeo-state.jsonplan_approved=true,plan_gate_status="manual_approved" → 执行
    5. 反馈时 → 修订 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 中相同的模式。

先决条件(由预检自动解析):

  1. npx agentation-mcp server (HTTP :4747) 正在运行 — 如果未运行,则自动启动
  2. agentation npm 包已安装在项目中 — 如果缺失,则自动安装
  3. <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.activetrue,并设置 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 钩子事件使用 BeforeToolAfterAgent
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. 最佳实践

  1. 计划先行:在执行前始终使用 ralph+plannotator 审查计划(及早发现错误方法)
  2. 团队优先:在 Claude Code 中,omc 团队模式效率最高
  3. bmad 回退:在没有团队的环境中使用 BMAD(Codex、Gemini)
  4. 工作树清理:工作完成后立即运行 worktree-cleanup.sh(防止分支污染)
  5. 状态持久性:使用 .omc/state/jeo-state.json 在会话间保持状态
  6. 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/healthcurl 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. 参考链接

📄 原始文档

完整文档(英文):

https://skills.sh/supercent-io/skills-template/jeo

💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。