본문으로 건너뛰기
cccskills
무료GitHub에 공개

welcome

Get started with Ouroboros through an interactive introduction that checks setup readiness and asks about your goals. Learn the core commands, then move into a project interview, a tutorial, or the help reference.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

원문원문 설명 보기

First-touch experience for new Ouroboros users

설치 방법 보기

이럴 때 유용합니다

  • Getting an introduction to Ouroboros
  • Checking setup before starting work
  • Starting a project or choosing a tutorial
  • Reviewing legacy Codex model settings

포함된 파일(1)

  • SKILL.md24.6 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

/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 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

auto

무료

Turn a multi-file development task or technology migration into a specification with acceptance criteria, then launch background implementation and verification. The workflow clarifies missing requirements, reviews the specification, and tracks progress and blockers through linked jobs.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Implementing a feature across multiple files
  • Migrating a framework or programming language
  • Replacing authentication, storage, or API layers
Q00/ouroboros6.2천2026년 10월 19일 업데이트

Register and search existing Git repositories and worktrees, then choose which projects Ouroboros interviews use as context. You can also generate a configuration containing verified build, test, and other check commands for the evaluation workflow.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Selecting existing projects as interview context
  • Finding registered repositories by topic
  • Rescanning after repositories are added or moved
Q00/ouroboros6.2천2026년 10월 19일 업데이트

cancel

무료

Stop stuck Ouroboros executions or background jobs by ID, or cancel all running and paused executions in the current project. It reports whether cancellation is complete or has been requested, with guidance for checking the final status.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Stopping a stuck execution
  • Cancelling a background job by ID
  • Cancelling all active executions in a project
Q00/ouroboros6.2천2026년 10월 19일 업데이트

evaluate

무료

Verify finished work against acceptance criteria using executable checks and a review of whether each requirement is met. Multiple models can review uncertain cases, and rejected work can enter an automated repair loop when the required Seed is available.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Checking finished work against its specification
  • Verifying observed behavior against acceptance criteria
  • Requesting multiple model reviews for uncertain results
Q00/ouroboros6.2천2026년 10월 19일 업데이트

evolve

무료

Start and monitor an Ouroboros development loop that revises project concepts and acceptance criteria, the conditions for judging completion. Run and evaluate successive generations, focus revisions on failed criteria, inspect progress, or rewind to an earlier generation.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Refining a project through repeated execution and evaluation
  • Inspecting progress across generations
  • Rewinding a development loop to an earlier generation
Q00/ouroboros6.2천2026년 10월 19일 업데이트

interview

무료

Turn a vague development idea into clear goals, constraints, and acceptance criteria through a guided interview. It checks unresolved decisions and confirms the agreed goal before moving toward a Seed, the requirements document used by Ouroboros.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Clarifying a vague idea before development
  • Defining completion criteria for a new feature
  • Agreeing on scope and constraints
Q00/ouroboros6.2천2026년 10월 19일 업데이트

Q00의 스킬 모두 보기

이 스킬의 문제 신고