welcome について
welcome は Ouroboros の新規ユーザー向け対話型オンボーディングスキルです。実行環境の確認や設定、コマンドの紹介を行い、スキップや再実行にも対応して完了状態を記録します。
主な機能
- 01Claude Code と Codex の設定確認
- 02対話形式の実行環境セットアップ案内
- 03モデル選択と移行の確認
- 04Ouroboros コマンドの紹介
- 05完了状態とスキップ設定の記録
活用シーン
- 01Ouroboros の初回利用時の案内
- 02実行環境の準備状況の確認
- 03Codex のモデル動作の選択
- 04オンボーディングの再実行やスキップ
MCP 対応
Claude Code または Codex の MCP 設定が準備できているか確認し、必要に応じてセットアップを案内します。MCP 対応コマンドには、サポート対象のホスト設定が必要です。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ q00/ ouroboros --skill welcomeインストール後、Claude Code で/welcomeを入力して読み込まれたか確認します。
詳細
/ouroboros:welcome
Ouroboros を初めて使うユーザー向けの対話型オンボーディングです。
使用方法
/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
手順
アクティブなランタイムの ask_user 機能を使って、すべての質問をユーザーの言語で尋ねてください。以下の韓国語ラベルが正式な表記です。
Python ランタイム(必須)
以下のスニペットを実行する前に、同じシェル内でこのリゾルバーを定義してください。Python 3.12 以降のみを受け付け(python3、次に python、次に uv)、引数と標準入力をそのまま保持します。ouroboros_python に渡すすべての引数を引用符で囲んでください。
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
}
事前確認:すでに完了していますか?
リゾルバー、このセクションのブロック、以下の移行チェックを、1 回のシェル呼び出しで実行してから、次のコマンドで結果を出力してください。
printf 'completed=%s setup=%s codex=%s migration=%s\n' "$WELCOME_COMPLETED" "${SETUP_READY:-}" "${CODEX_READY:-}" "${LEGACY_CODEX_MODEL_MIGRATION_REQUIRED:-}"。
完了マーカーを読み取ります(従来の welcomeShown: true も該当します)。
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
)
完了マーカーを有効にする前に、アクティブなランタイムでセットアップが準備できているか確認してください。 以前にウェルカムを完了していても、나중에を選んだユーザーや、後からセットアップが削除されたユーザーに、セットアップの案内を表示しないままにしてはいけません。
Claude Code は、~/.ouroboros/config.yaml の orchestrator.runtime_backend が {claude, claude_mcp} のいずれかで、llm.backend: claude の場合に準備完了です。マーケットプレイスプラグインが自身の MCP 登録を管理するため、ホストが管理する ~/.claude/mcp.json は準備状況の判定に一切含めません。
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
SETUP_READY が true でない場合は、Codex を確認してください。両方のバックエンドが codex で、Codex CLI(OUROBOROS_CODEX_CLI_PATH、次に orchestrator.codex_cli_path、それ以外は PATH 上の codex)が実行可能であり、$CODEX_HOME/config.toml の mcp_servers\.ouroboros(TOML のキー表記は問いません)に実行可能な command または空白以外の 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
Codex の従来モデル設定の移行
以前の設定では、4 つすべてのステージモデルフィールドに gpt-5 が保存されていました。これは現在、Codex App/CLI でのモデル変更を反映させない明示的な固定設定です。ユーザーが指定した可能性のある固定設定を、黙って書き換えてはいけません。Codex の準備ができている場合は、この従来の設定状態(または中断された移行)を一度だけ検出してください。
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
CODEX_READY と LEGACY_CODEX_MODEL_MIGRATION_REQUIRED の両方が true の場合は、「현재 설정은 모든 단계에서 gpt-5를 고정해 두고 있어요. Codex에서 선택한 모델을 자동으로 사용하도록 바꿀까요?」(ヘッダー 모델 설정)と尋ね、次の選択肢を提示してください。
- Codex 선택으로 전환하기 (권장):App または CLI で変更したモデルを、すべてのステージで自動的に使用します。 4 つの固定設定をアトミックに書き換えます。
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 は Codex にモデル固定を送信しないという意味であり、"default" という名前のモデルではありません。判断を記録する前に、書き換えが成功したことを確認してください。書き換えが中断されて gpt-5/default が混在した状態になった場合、次回の確認時に再度選択肢を提示します。
- gpt-5 고정 유지하기:これまでどおり、すべてのステージで gpt-5 を使い続けます。
config.yamlは変更しないでください。
どちらを選んだ場合も、既存のキーを保持しながら、~/.ouroboros/prefs.json に codexModelMigration マーカーを 1 つだけマージしてください。
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
維持する選択肢の場合は、automatic-v1 の代わりに kept-gpt-5-v1 を渡してください。ウェルカムがすでに完了している場合は、簡潔に確認して終了します。一般的なウェルカムの質問も尋ねてはいけません。
事前確認後の分岐
- 完了済みで、
SETUP_READYまたはCODEX_READYが true、かつ--forceなし:Ouroboros welcome was already completed on $WELCOME_COMPLETED. What would you like to do?と尋ね、Skip(作業を続行する。推奨。終了)と Re-run welcome(ステップ 1 に進む)を提示します。 - 完了済みだが、どちらも準備できていない:このプロンプトを省略して、セットアップゲートに進みます。
--skip:完了設定を書き込み(ステップ 4)、Ouroboros welcome skipped. Run /ouroboros:welcome --force to re-run onboarding.を出力して終了します。
セットアップゲート:初回使用
Pre-Check が出力した準備状況を使用してください。グローバルの config.yaml だけでは不十分です。ただし、これらのゲートが認識するランタイムが指定されている場合は除きます。セットアップの実行後、または Pre-Check が実行されなかった場合は、判定を出力する次のスタンドアロンゲートを使用して再確認してください。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
SETUP_READY と出力された場合は、Codex のゲートをスキップしてステップ 1 に進んでください。それ以外の場合は 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
どちらも準備できていない場合(SETUP_REQUIRED と CODEX_SETUP_REQUIRED の場合。どちらのゲートも認識しないランタイムが指定された設定を含みます)は、「Ouroborosを初めてお使いですね。始める前に実行環境を設定しますか?」と尋ねてください(見出しは Ouroborosを始める)。
- 設定して始める(おすすめ):一度設定すれば、すぐに使えます。アクティブなホスト向けのセットアップを自分で実行してください。ホストが実行できるコマンドをユーザーにコピーさせないでください。Codex App または Codex CLI では、実行ファイルがインストールされている場合、
ouroboros setup --runtime codexを実行してください。Marketplace プラグインのみをインストールしている場合は、代わりにuvx --isolated --python '>=3.12' --from 'ouroboros-ai[mcp]' ouroboros setup --runtime codexを実行してください。Claude Code では、../setup/SKILL.mdに従ってください。 - 後で:今は基本的な案内だけを見て、設定は後で行います。MCP に依存する機能が利用可能だと断言せずに、ウェルカムフローを続けてください。
Codex のセットアップが成功した後は、「設定が完了しました。デフォルトでは、Codex で選択したモデルを使用します。モデルはいつでも後から変更できます。」と尋ねてください(見出しは 準備完了)。
- すぐに始める(おすすめ):デフォルトのモデルですぐに作業を始めます。ステップ 1 に進んでください。
- モデルを自分で設定する:段階ごとにモデルを変更するか、一覧にないモデル ID を入力して固定します。
../config/SKILL.mdを読み、手順に従ってください。ユーザーのローカルの Codex App または CLI では、ブラウザーで一時的なlocalhostアドレスが開きます(外部サイトではありません)。意図的に特定の段階のモデルを固定するための Use Codex default model と Enter another model ID… が表示されます。設定セッションが終了したら、ステップ 1 に進んでください。
Claude Code では、../setup/SKILL.md が同等のモデル選択を独自に尋ねるため、もう一度尋ねないでください。ランタイムの準備ができたら、このゲートを再度表示しないでください。設定 UI は ooo config から引き続き利用できます。
ステップ 1:バナー
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 -----+
通常の Claude セットアップでは、MCP 1.x のデフォルトの [claude] Agent SDK プロファイルを使用します。ヘルスチェックとして ~/.claude/mcp.json を調べたり変更したりしないでください。ここで Ouroboros MCP ツールを呼び出せない場合は、MCP に依存するコマンドには、独立した [mcp] ランチャーを管理する、サポート対象のホストセットアップが必要だと説明してください。[claude-sdk] と [mcp] が同時にインストールされることはありません。
ステップ 2:ペルソナ
New project idea(漠然としたアイデアを Seed にまとめる)、Tired of rewriting prompts(AI が何度も違うものを作ってしまう)、Just exploring を提示して、「Ouroborosを使って、どんなことをしたいですか?」と尋ねてください。相手に合わせて 1~2 文で返答してください。
ステップ 3:最初のアクション
基本的なコマンドを示してください:ooo interview(隠れた前提を明らかにするソクラテス式の質疑応答)、ooo seed(回答を Seed に固定する)、ooo run(Seed を実行する)、ooo evaluate(受け入れ基準に照らして検証する)、ooo unstuck(水平思考)、ooo config(設定)、ooo help(完全なリファレンス)。
「最初に何をしたいですか?」と尋ねてください。
- プロジェクトを始める:「何を作りたいですか?」と尋ねてから、
ooo interviewとして続けてください。 - チュートリアルを試す:
ooo tutorialとして続けてください。 - ドキュメントを読む:
ooo helpとして続けてください。
会話を引き継ぐ前にステップ 4 を実行してください。次のコマンドが会話を引き継ぐ場合でも、完了が記録されるようにします。
ステップ 4:GitHub でのスターと完了
gh auth status &>/dev/null && echo GH_OK || echo GH_MISSING を実行します。GH_OK であり、~/.ouroboros/prefs.json の star_asked が true でない場合は、「Ouroboros を気に入っていただけたら、GitHub でスターを付けていただけますか?」と尋ね、GitHub でスターを付ける(gh api -X PUT /user/starred/Q00/ouroboros を実行)と後でを提示します。
既存のキーを保持したまま、完了フィールドを ~/.ouroboros/prefs.json にマージします。スターに関する質問をした場合は、質問が繰り返されないよう、コマンドの先頭に STAR_ASKED=true を付けます。
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
引き継ぐ前に、「interview me」、「I'm stuck」、「evaluate this」のようなフレーズも該当するコマンドに振り分けられることを伝えてください。また、ooo run や ooo evolve の動作をリアルタイムで確認するには、別のターミナルで uvx --python '>=3.12' --from 'ouroboros-ai[tui]' ouroboros tui monitor を実行します。
RFC #1392 状態を示すフッター
最終回答の末尾に、◆ <現在の状態> → next: <推奨アクション> の形式で、必ず 1 行だけ記載してください。利用可能な場合は ouroboros_session_status を使ってライブセッションの状態を取得し、それ以外の場合はこのスキルでの実際の結果から状態を判断します。「ステップ N / M」の形式のフッターは使用しないでください。次のステップが実際の選択肢である場合は、2~3 個の選択肢を記載します。