跳到正文
cccskills
免费在 GitHub 公开

welcome

First-touch experience for new Ouroboros users

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(1)

  • SKILL.md24.6 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

/ouroboros:welcome

Interactive onboarding for new Ouroboros users.

Usage

/ouroboros:welcome              # First-time or update onboarding
/ouroboros:welcome --skip       # Skip welcome, mark as shown
/ouroboros:welcome --force      # Force re-run welcome even if shown

Instructions

Ask every question with the active runtime's ask_user capability, in the user's language. The Korean labels below are the canonical wording.

Python Runtime (Required)

Define this resolver in the same shell before any snippet below. It accepts only Python 3.12 or newer (python3, then python, then uv) and preserves arguments and stdin. Quote every argument passed to ouroboros_python.

<!-- ouroboros-python-resolver:start -->
ouroboros_python() {
  if command -v python3 >/dev/null 2>&1 &&
    (unset PYTHONHOME PYTHONPATH PYTHONPLATLIBDIR PYTHONEXECUTABLE __PYVENV_LAUNCHER__; command python3 -c 'import sys; raise SystemExit(sys.version_info < (3, 12))') >/dev/null 2>&1
  then
    (unset PYTHONHOME PYTHONPATH PYTHONPLATLIBDIR PYTHONEXECUTABLE __PYVENV_LAUNCHER__; command python3 "$@")
    return
  fi
  if command -v python >/dev/null 2>&1 &&
    (unset PYTHONHOME PYTHONPATH PYTHONPLATLIBDIR PYTHONEXECUTABLE __PYVENV_LAUNCHER__; command python -c 'import sys; raise SystemExit(sys.version_info < (3, 12))') >/dev/null 2>&1
  then
    (unset PYTHONHOME PYTHONPATH PYTHONPLATLIBDIR PYTHONEXECUTABLE __PYVENV_LAUNCHER__; command python "$@")
    return
  fi
  if command -v uv >/dev/null 2>&1; then
    (unset PYTHONHOME PYTHONPATH PYTHONPLATLIBDIR PYTHONEXECUTABLE __PYVENV_LAUNCHER__; command uv run --no-project --quiet --python '>=3.12' python "$@")
    return
  fi
  printf '%s\n' 'Ouroboros skills require Python >= 3.12 or uv on PATH.' >&2
  return 127
}
<!-- ouroboros-python-resolver:end -->

Pre-Check: Already Completed?

Run the resolver, this section's blocks, and the migration check below in one shell call, then print the result with printf 'completed=%s setup=%s codex=%s migration=%s\n' "$WELCOME_COMPLETED" "${SETUP_READY:-}" "${CODEX_READY:-}" "${LEGACY_CODEX_MODEL_MIGRATION_REQUIRED:-}".

Read the completion marker (legacy welcomeShown: true also counts):

WELCOME_COMPLETED=$(ouroboros_python - <<'PY'
import json, os
try:
    prefs = json.load(open(os.path.expanduser('~/.ouroboros/prefs.json'), encoding='utf-8'))
except Exception:
    prefs = {}
if not isinstance(prefs, dict):
    prefs = {}
print(prefs.get('welcomeCompleted') or ('legacy-welcomeShown' if prefs.get('welcomeShown') else ''))
PY
)

Before honoring that completion marker, determine whether setup is ready for the active runtime. A previously completed welcome must never hide the setup gate from a user who chose 나중에 or whose setup was later removed.

Claude Code is ready when ~/.ouroboros/config.yaml has orchestrator.runtime_backend in {claude, claude_mcp} and llm.backend: claude. The marketplace plugin owns its MCP registration, so host-owned ~/.claude/mcp.json is never part of readiness:

if ouroboros_python - "$HOME/.ouroboros/config.yaml" <<'PY'
import sys
from pathlib import Path

try:
    import yaml
except ModuleNotFoundError:
    yaml = None


def scalar(raw: str) -> str:
    return raw.strip().split(" #", 1)[0].strip().rstrip(",}").strip().strip("'\"")


def load_yaml(path: str) -> dict:
    source = Path(path).read_text(encoding="utf-8")
    if yaml is not None:
        loaded = yaml.safe_load(source) or {}
        return loaded if isinstance(loaded, dict) else {}
    parsed: dict[str, dict[str, str]] = {}
    section = None
    for line in source.splitlines():
        if not line.strip() or line.lstrip().startswith("#"):
            continue
        key, separator, value = line.strip().partition(":")
        if not separator:
            continue
        key = key.strip("'\"")
        if not line[0].isspace():
            section = key
            parsed[section] = {}
            flow = value.strip().split(" #", 1)[0].strip()
            if flow.startswith("{") and flow.endswith("}"):
                for part in flow[1:-1].split(","):
                    field, separator, field_value = part.partition(":")
                    if separator:
                        parsed[section][field.strip().strip("'\"")] = scalar(field_value)
        elif section is not None:
            parsed[section][key] = scalar(value)
    return parsed


try:
    config = load_yaml(sys.argv[1])
except (OSError, ValueError):
    raise SystemExit(1)
orchestrator, llm = config.get("orchestrator"), config.get("llm")
ready = (
    isinstance(orchestrator, dict)
    and orchestrator.get("runtime_backend") in {"claude", "claude_mcp"}
    and isinstance(llm, dict)
    and llm.get("backend") == "claude"
)
raise SystemExit(0 if ready else 1)
PY
then
  SETUP_READY="true"
fi

If SETUP_READY is not true, check Codex. It is ready when both backends are codex, the Codex CLI (OUROBOROS_CODEX_CLI_PATH, else orchestrator.codex_cli_path, else codex on PATH) is runnable, and mcp_servers\.ouroboros in $CODEX_HOME/config.toml (any TOML key spelling) has a runnable command or a non-blank url:

CODEX_HOME_DIR="${CODEX_HOME:-$HOME/.codex}"
case "$CODEX_HOME_DIR" in
  "~") CODEX_HOME_DIR="$HOME" ;;
  "~/"*) CODEX_HOME_DIR="$HOME/${CODEX_HOME_DIR#"~/"}" ;;
esac
if ouroboros_python - "$HOME/.ouroboros/config.yaml" "$CODEX_HOME_DIR/config.toml" <<'PY'
import os
import shutil
import sys
import tomllib
from pathlib import Path

try:
    import yaml
except ModuleNotFoundError:
    yaml = None


def scalar(raw: str) -> str:
    return raw.strip().split(" #", 1)[0].strip().rstrip(",}").strip().strip("'\"")


def load_yaml(path: str) -> dict:
    source = Path(path).read_text(encoding="utf-8")
    if yaml is not None:
        loaded = yaml.safe_load(source) or {}
        return loaded if isinstance(loaded, dict) else {}
    parsed: dict[str, dict[str, str]] = {}
    section = None
    for line in source.splitlines():
        if not line.strip() or line.lstrip().startswith("#"):
            continue
        key, separator, value = line.strip().partition(":")
        if not separator:
            continue
        key = key.strip("'\"")
        if not line[0].isspace():
            section = key
            parsed[section] = {}
            flow = value.strip().split(" #", 1)[0].strip()
            if flow.startswith("{") and flow.endswith("}"):
                for part in flow[1:-1].split(","):
                    field, separator, field_value = part.partition(":")
                    if separator:
                        parsed[section][field.strip().strip("'\"")] = scalar(field_value)
        elif section is not None:
            parsed[section][key] = scalar(value)
    return parsed


def runnable(candidate: str) -> bool:
    value = candidate.strip()
    if not value:
        return False
    if "/" not in value:
        return shutil.which(value) is not None
    path = Path(value).expanduser()
    return path.is_file() and os.access(path, os.X_OK)


def mcp_ready(entry: object) -> bool:
    if not isinstance(entry, dict):
        return False
    command, url = entry.get("command"), entry.get("url")
    if isinstance(command, str) and command.strip():
        return runnable(command)
    return isinstance(url, str) and bool(url.strip())


try:
    config = load_yaml(sys.argv[1])
    codex_config = tomllib.loads(Path(sys.argv[2]).read_text(encoding="utf-8"))
except (OSError, ValueError):
    raise SystemExit(1)
orchestrator, llm = config.get("orchestrator"), config.get("llm")
servers = codex_config.get("mcp_servers")
cli_path = os.environ.get("OUROBOROS_CODEX_CLI_PATH")
if not cli_path and isinstance(orchestrator, dict):
    cli_path = orchestrator.get("codex_cli_path")
if not isinstance(cli_path, str) or not cli_path.strip():
    cli_path = "codex"
ready = (
    isinstance(orchestrator, dict)
    and orchestrator.get("runtime_backend") == "codex"
    and isinstance(llm, dict)
    and llm.get("backend") == "codex"
    and runnable(cli_path)
    and mcp_ready(servers.get("ouroboros") if isinstance(servers, dict) else None)
)
raise SystemExit(0 if ready else 1)
PY
then
  CODEX_READY="true"
fi

Legacy Codex Model Migration

Older configurations saved gpt-5 into all four stage-model fields. That is now an explicit pin that stops Codex App/CLI model changes from taking effect. Never rewrite a possible user pin silently. When Codex is ready, detect that exact legacy shape (or an interrupted migration) once:

if ouroboros_python - "$HOME/.ouroboros/config.yaml" "$HOME/.ouroboros/prefs.json" <<'PY'
from __future__ import annotations

import json
import sys
from pathlib import Path

config_path, prefs_path = map(Path, sys.argv[1:])

def yaml_mapping(source: str) -> dict[str, dict[str, str]]:
    parsed: dict[str, dict[str, str]] = {}
    section: str | None = None
    for raw_line in source.splitlines():
        if not raw_line.strip() or raw_line.lstrip().startswith("#"):
            continue
        indent = len(raw_line) - len(raw_line.lstrip())
        key, separator, raw_value = raw_line.strip().partition(":")
        if not separator:
            continue
        value = raw_value.strip().split(" #", 1)[0].strip().strip("'\"")
        if indent == 0:
            section = key.strip("'\"")
            parsed.setdefault(section, {})
        elif section is not None:
            parsed[section][key.strip("'\"")] = value
    return parsed

try:
    config = yaml_mapping(config_path.read_text(encoding="utf-8"))
except OSError:
    raise SystemExit(1)
try:
    prefs = json.loads(prefs_path.read_text(encoding="utf-8"))
except (OSError, ValueError):
    prefs = {}
if not isinstance(prefs, dict):
    prefs = {}

stage_values = (
    config.get("clarification", {}).get("default_model"),
    config.get("execution", {}).get("default_model"),
    config.get("evaluation", {}).get("semantic_model"),
    config.get("resilience", {}).get("reflect_model"),
)
legacy_gpt5 = all(value == "gpt-5" for value in stage_values)
partial_automatic_migration = (
    any(value == "gpt-5" for value in stage_values)
    and any(value == "default" for value in stage_values)
    and all(value in {"gpt-5", "default"} for value in stage_values)
)
handled = prefs.get("codexModelMigration") in {"automatic-v1", "kept-gpt-5-v1"}
raise SystemExit(0 if (legacy_gpt5 or partial_automatic_migration) and not handled else 1)
PY
then
  LEGACY_CODEX_MODEL_MIGRATION_REQUIRED="true"
fi

If CODEX_READY and LEGACY_CODEX_MODEL_MIGRATION_REQUIRED are both true, ask "현재 설정은 모든 단계에서 gpt-5를 고정해 두고 있어요. Codex에서 선택한 모델을 자동으로 사용하도록 바꿀까요?" (header 모델 설정) with these options:

  • Codex 선택으로 전환하기 (권장): App이나 CLI에서 바꾼 모델을 모든 단계가 자동으로 따라가요. Atomically rewrite the four pins:
ouroboros_python - "$HOME/.ouroboros/config.yaml" <<'PY'
from __future__ import annotations

import os
import sys
import tempfile
from pathlib import Path

path = Path(sys.argv[1])
original = path.read_text(encoding="utf-8")
replacements = {
    ("clarification", "default_model"): "default",
    ("execution", "default_model"): "default",
    ("evaluation", "semantic_model"): "default",
    ("resilience", "reflect_model"): "default",
}
seen: set[tuple[str, str]] = set()
section: str | None = None
output: list[str] = []
for line in original.splitlines(keepends=True):
    stripped = line.strip()
    indent = len(line) - len(line.lstrip())
    key = stripped.split(":", 1)[0].strip("'\"") if ":" in stripped else ""
    if indent == 0 and ":" in stripped:
        section = key
    target = (section or "", key)
    if indent > 0 and target in replacements:
        newline = "\n" if line.endswith("\n") else ""
        prefix = line[:indent]
        comment = ""
        value_part = line.strip().split(":", 1)[1]
        if " #" in value_part:
            comment = " #" + value_part.split(" #", 1)[1].rstrip("\n")
        output.append(f"{prefix}{key}: {replacements[target]}{comment}{newline}")
        seen.add(target)
    else:
        output.append(line)
missing = set(replacements) - seen
if missing:
    raise SystemExit(f"Cannot migrate Codex model pins; missing keys: {sorted(missing)}")
updated = "".join(output)
fd, tmp_name = tempfile.mkstemp(prefix=".config.yaml.", dir=str(path.parent))
try:
    with os.fdopen(fd, "w", encoding="utf-8") as tmp:
        tmp.write(updated)
        tmp.flush()
        os.fsync(tmp.fileno())
    os.replace(tmp_name, path)
finally:
    try:
        os.unlink(tmp_name)
    except FileNotFoundError:
        pass
PY

default sends no model pin to Codex; it is not a model named "default". Confirm the rewrite succeeded before recording the decision. An interrupted rewrite leaves a partial gpt-5/default state that the next check offers again.

  • gpt-5 고정 유지하기: 지금처럼 모든 단계를 gpt-5로 계속 실행해요. Do not change config.yaml.

For either choice, merge exactly one codexModelMigration marker into ~/.ouroboros/prefs.json, keeping existing keys:

ouroboros_python - "automatic-v1" <<'PY'
import json, os, sys
path = os.path.expanduser('~/.ouroboros/prefs.json')
try:
    prefs = json.load(open(path, encoding='utf-8'))
except Exception:
    prefs = {}
if not isinstance(prefs, dict):
    prefs = {}
prefs['codexModelMigration'] = sys.argv[1]
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, 'w', encoding='utf-8') as f:
    json.dump(prefs, f, indent=2)
    f.write('\n')
PY

Pass kept-gpt-5-v1 instead of automatic-v1 for the keep choice. If welcome was already completed, confirm briefly and exit; do not also ask the generic welcome question.

Routing After the Pre-Check

  • Completed, SETUP_READY or CODEX_READY true, no --force: ask "Ouroboros welcome was already completed on $WELCOME_COMPLETED. What would you like to do?" with Skip (continue to work, recommended; exit) and Re-run welcome (continue to Step 1).
  • Completed but neither ready: skip that prompt and go to the Setup Gate.
  • --skip: write the completion prefs (Step 4), print Ouroboros welcome skipped. Run /ouroboros:welcome --force to re-run onboarding., and exit.

Setup Gate: First Use

Use the readiness the Pre-Check printed; a global config.yaml alone is not enough unless it names a runtime these gates recognize. To recheck after a setup run (or when the Pre-Check did not run), use these standalone gates, which print their verdict. Claude Code:

if ouroboros_python - "$HOME/.ouroboros/config.yaml" <<'PY'
import sys
from pathlib import Path

try:
    import yaml
except ModuleNotFoundError:
    yaml = None


def scalar(raw: str) -> str:
    return raw.strip().split(" #", 1)[0].strip().rstrip(",}").strip().strip("'\"")


def load_yaml(path: str) -> dict:
    source = Path(path).read_text(encoding="utf-8")
    if yaml is not None:
        loaded = yaml.safe_load(source) or {}
        return loaded if isinstance(loaded, dict) else {}
    parsed: dict[str, dict[str, str]] = {}
    section = None
    for line in source.splitlines():
        if not line.strip() or line.lstrip().startswith("#"):
            continue
        key, separator, value = line.strip().partition(":")
        if not separator:
            continue
        key = key.strip("'\"")
        if not line[0].isspace():
            section = key
            parsed[section] = {}
            flow = value.strip().split(" #", 1)[0].strip()
            if flow.startswith("{") and flow.endswith("}"):
                for part in flow[1:-1].split(","):
                    field, separator, field_value = part.partition(":")
                    if separator:
                        parsed[section][field.strip().strip("'\"")] = scalar(field_value)
        elif section is not None:
            parsed[section][key] = scalar(value)
    return parsed


try:
    config = load_yaml(sys.argv[1])
except (OSError, ValueError):
    raise SystemExit(1)
orchestrator, llm = config.get("orchestrator"), config.get("llm")
ready = (
    isinstance(orchestrator, dict)
    and orchestrator.get("runtime_backend") in {"claude", "claude_mcp"}
    and isinstance(llm, dict)
    and llm.get("backend") == "claude"
)
raise SystemExit(0 if ready else 1)
PY
then
  echo "SETUP_READY"
else
  echo "SETUP_REQUIRED"
fi

If that printed SETUP_READY, skip the Codex gate and continue to Step 1. Otherwise check Codex:

CODEX_HOME_DIR="${CODEX_HOME:-$HOME/.codex}"
case "$CODEX_HOME_DIR" in
  "~") CODEX_HOME_DIR="$HOME" ;;
  "~/"*) CODEX_HOME_DIR="$HOME/${CODEX_HOME_DIR#"~/"}" ;;
esac
if ouroboros_python - "$HOME/.ouroboros/config.yaml" "$CODEX_HOME_DIR/config.toml" <<'PY'
import os
import shutil
import sys
import tomllib
from pathlib import Path

try:
    import yaml
except ModuleNotFoundError:
    yaml = None


def scalar(raw: str) -> str:
    return raw.strip().split(" #", 1)[0].strip().rstrip(",}").strip().strip("'\"")


def load_yaml(path: str) -> dict:
    source = Path(path).read_text(encoding="utf-8")
    if yaml is not None:
        loaded = yaml.safe_load(source) or {}
        return loaded if isinstance(loaded, dict) else {}
    parsed: dict[str, dict[str, str]] = {}
    section = None
    for line in source.splitlines():
        if not line.strip() or line.lstrip().startswith("#"):
            continue
        key, separator, value = line.strip().partition(":")
        if not separator:
            continue
        key = key.strip("'\"")
        if not line[0].isspace():
            section = key
            parsed[section] = {}
            flow = value.strip().split(" #", 1)[0].strip()
            if flow.startswith("{") and flow.endswith("}"):
                for part in flow[1:-1].split(","):
                    field, separator, field_value = part.partition(":")
                    if separator:
                        parsed[section][field.strip().strip("'\"")] = scalar(field_value)
        elif section is not None:
            parsed[section][key] = scalar(value)
    return parsed


def runnable(candidate: str) -> bool:
    value = candidate.strip()
    if not value:
        return False
    if "/" not in value:
        return shutil.which(value) is not None
    path = Path(value).expanduser()
    return path.is_file() and os.access(path, os.X_OK)


def mcp_ready(entry: object) -> bool:
    if not isinstance(entry, dict):
        return False
    command, url = entry.get("command"), entry.get("url")
    if isinstance(command, str) and command.strip():
        return runnable(command)
    return isinstance(url, str) and bool(url.strip())


try:
    config = load_yaml(sys.argv[1])
    codex_config = tomllib.loads(Path(sys.argv[2]).read_text(encoding="utf-8"))
except (OSError, ValueError):
    raise SystemExit(1)
orchestrator, llm = config.get("orchestrator"), config.get("llm")
servers = codex_config.get("mcp_servers")
cli_path = os.environ.get("OUROBOROS_CODEX_CLI_PATH")
if not cli_path and isinstance(orchestrator, dict):
    cli_path = orchestrator.get("codex_cli_path")
if not isinstance(cli_path, str) or not cli_path.strip():
    cli_path = "codex"
ready = (
    isinstance(orchestrator, dict)
    and orchestrator.get("runtime_backend") == "codex"
    and isinstance(llm, dict)
    and llm.get("backend") == "codex"
    and runnable(cli_path)
    and mcp_ready(servers.get("ouroboros") if isinstance(servers, dict) else None)
)
raise SystemExit(0 if ready else 1)
PY
then
  echo "CODEX_READY"
else
  echo "CODEX_SETUP_REQUIRED"
fi

If neither is ready (SETUP_REQUIRED and CODEX_SETUP_REQUIRED, including a config that names a runtime neither gate recognizes), ask "Ouroboros를 처음 사용하시네요. 시작하기 전에 실행 환경을 설정할까요?" (header Ouroboros 시작하기):

  • 설정하고 시작하기 (권장): 한 번만 설정하면 바로 사용할 수 있어요. Run the setup for the active host yourself; never ask the user to copy a command the host can run. In Codex App or Codex CLI, run ouroboros setup --runtime codex when the executable is installed. For a Marketplace-plugin-only install run uvx --isolated --python '>=3.12' --from 'ouroboros-ai[mcp]' ouroboros setup --runtime codex instead. In Claude Code, follow ../setup/SKILL.md.
  • 나중에: 지금은 기본 안내만 보고 나중에 설정할게요. Continue the welcome flow without claiming MCP-backed features are ready.

After a successful Codex setup, ask "설정이 완료됐어요. 기본적으로 Codex에서 선택한 모델을 사용합니다. 모델은 언제든 나중에 바꿀 수 있어요." (header 준비 완료):

  • 바로 시작하기 (권장): 기본 모델로 바로 작업을 시작해요. Continue to Step 1.
  • 직접 모델 설정하기: 단계별로 모델을 바꾸거나 목록에 없는 모델 ID를 입력해 고정해요. Read and follow ../config/SKILL.md. On the user's local Codex App or CLI it opens the settings UI in their browser at a temporary localhost address (not an external website). It offers Use Codex default model and Enter another model ID… for a deliberate stage pin. Continue to Step 1 when the settings session ends.

In Claude Code, ../setup/SKILL.md asks the equivalent model question itself; do not ask it again. Do not show this gate again once a runtime is ready; the settings UI stays available through ooo config.

Step 1: Banner

Welcome to Ouroboros!

Most AI coding fails at the input, not the output.
Ouroboros exposes hidden assumptions BEFORE any code is written.

Interview -> Seed -> Execute -> Evaluate
    ^                            |
    +---- Evolutionary Loop -----+

Ordinary Claude setup uses the default [claude] Agent SDK profile on MCP 1.x. Never inspect or mutate ~/.claude/mcp.json as a health check. If Ouroboros MCP tools are not callable here, say that MCP-backed commands need a supported host setup, which owns an isolated [mcp] launcher; [claude-sdk] and [mcp] are never installed together.

Step 2: Persona

Ask "What brings you to Ouroboros?" with New project idea (crystallize a vague idea into a Seed), Tired of rewriting prompts (AI keeps building the wrong thing), and Just exploring. Reply in 1-2 personalized sentences.

Step 3: First Action

Show the core commands: ooo interview (Socratic Q&A that exposes hidden assumptions), ooo seed (freeze answers into a Seed), ooo run (execute a Seed), ooo evaluate (verify against the acceptance criteria), ooo unstuck (lateral thinking), ooo config (settings), ooo help (full reference).

Ask "What would you like to do first?":

  • Start a project: ask "What do you want to build?", then continue as ooo interview.
  • Try the tutorial: continue as ooo tutorial.
  • Read the docs: continue as ooo help.

Run Step 4 before handing off, so completion is recorded even when the next command takes over the conversation.

Step 4: GitHub Star and Completion

Run gh auth status &>/dev/null && echo GH_OK || echo GH_MISSING. If GH_OK and star_asked is not true in ~/.ouroboros/prefs.json, ask "If you're enjoying Ouroboros, would you like to star it on GitHub?" with Star on GitHub (run gh api -X PUT /user/starred/Q00/ouroboros) and Maybe later.

Then merge the completion fields into ~/.ouroboros/prefs.json, keeping existing keys. Prefix the command with STAR_ASKED=true when the star question was asked, so it is never repeated:

ouroboros_python - <<'PY'
import json, os
from datetime import UTC, datetime
path = os.path.expanduser('~/.ouroboros/prefs.json')
os.makedirs(os.path.dirname(path), exist_ok=True)
try:
    with open(path, encoding='utf-8') as f:
        prefs = json.load(f)
    if not isinstance(prefs, dict):
        prefs = {}
except Exception:
    prefs = {}
prefs.update({
    'welcomeShown': True,
    'welcomeCompleted': datetime.now(UTC).isoformat(),
})
if os.environ.get('STAR_ASKED') == 'true':
    prefs['star_asked'] = True
with open(path, 'w', encoding='utf-8') as f:
    json.dump(prefs, f, indent=2)
    f.write('\n')
PY

Before the handoff, mention that phrases like "interview me", "I'm stuck", or "evaluate this" also route to the matching command; to watch ooo run or ooo evolve live, run uvx --python '>=3.12' --from 'ouroboros-ai[tui]' ouroboros tui monitor in a separate terminal.

RFC #1392 State Breadcrumb Footer

End the final response with exactly one line ◆ <current state> → next: <recommended action>. Derive the state from live session state via ouroboros_session_status when available, otherwise from this skill's actual outcome. Never use a linear Step N of M footer; when the next step is a real choice, list 2-3 options.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

auto

免费

Use when the work spans several files or replaces a framework, language, auth, storage, or API layer (rewrites and migrations included), and the user wants it to end up working and tested. Asks only what is missing, writes a spec with acceptance criteria, then runs and verifies it in the background. Not for questions, small edits, or an existing Seed (use run).

中文简介正在准备中。当前显示原文说明。

Q00/ouroboros62472026年10月18日 更新

Scan and manage brownfield repository/worktree defaults for interviews

中文简介正在准备中。当前显示原文说明。

Q00/ouroboros62472026年10月18日 更新

cancel

免费

Cancel stuck or orphaned executions

中文简介正在准备中。当前显示原文说明。

Q00/ouroboros62472026年10月18日 更新

evaluate

免费

Use when the user wants proof that finished work meets its acceptance criteria, not just that tests pass: 'verify it is actually done', 'check it against the spec', 'evaluate the run'. Runs mechanical checks, a semantic review per criterion, and multi-model consensus when uncertain. With execution.auto_evolve on (the default), a rejected result with a Seed continues into a Ralph fix loop; pass auto_evolve: false to verify only.

中文简介正在准备中。当前显示原文说明。

Q00/ouroboros62472026年10月18日 更新

evolve

免费

Start or monitor an evolutionary development loop

中文简介正在准备中。当前显示原文说明。

Q00/ouroboros62472026年10月18日 更新

interview

免费

Use when the user wants to build or change something but the request is vague or open-ended: 'help me figure out what to build', 'I'm not sure what it should do', 'add X' with no details, or no clear definition of done. Runs a short Socratic interview that turns the idea into goals, constraints, and acceptance criteria before any code is written. Not for simple questions, small clear edits, or an existing Seed.

中文简介正在准备中。当前显示原文说明。

Q00/ouroboros62472026年10月18日 更新

查看 Q00 的全部技能

报告此技能的问题