diff --git a/.codex/skills/delegate-to-claude/SKILL.md b/.codex/skills/delegate-to-claude/SKILL.md new file mode 100644 index 0000000..acec94a --- /dev/null +++ b/.codex/skills/delegate-to-claude/SKILL.md @@ -0,0 +1,73 @@ +--- +name: delegate-to-claude +description: Delegate a bounded coding, investigation, or review task from Codex to Claude Code, then inspect and independently assess Claude's result. Use when the user asks Codex to delegate to Claude or when a second-model execution or review pass is explicitly desired. Do not use for ordinary Codex subagents or as a substitute for Codex's final review. +--- + +# Delegate to Claude Code + +Use Claude Code as an executor or independent reviewer while Codex remains the coordinator responsible for scope, evidence, and acceptance. + +## Preconditions + +1. Confirm `claude` is installed and authenticated by running `scripts/claude_delegate.sh check` from this skill directory. +2. Read the repository's applicable `AGENTS.md`, `CLAUDE.md`, and task-specific instructions before writing the work order. +3. Do not delegate secrets, provider writes, production mutations, releases, or destructive operations unless the user explicitly authorized that exact action. Claude receives no broader authority than Codex has. + +## Work order + +Write the task into a temporary Markdown file outside the repository unless the user requested a durable task artifact. Make it self-contained and include: + +- role: executor or read-only reviewer; +- exact objective and boundaries; +- working directory and relevant files; +- repository instructions Claude must read; +- allowed side effects and forbidden actions; +- required checks and expected evidence; +- requested return format: findings or changed files, commands run, results, and blockers. + +The helper adds an executor marker and tells Claude not to spawn further agents. Do not pass the user's whole conversation when a concise work order is sufficient. + +## Run + +From the target repository directory: + +```bash +/absolute/path/to/this-skill/scripts/claude_delegate.sh run /absolute/path/to/work-order.md /absolute/path/to/result.json +``` + +The default permission mode is `auto`, which lets Claude decide whether tools are safe to use. Override it only when the task requires a stricter mode: + +```bash +CLAUDE_DELEGATE_PERMISSION_MODE=plan scripts/claude_delegate.sh run work-order.md result.json +``` + +Optional environment variables: + +- `CLAUDE_DELEGATE_MODEL`: Claude model alias or full model name; default `sonnet`. +- `CLAUDE_DELEGATE_EFFORT`: `low`, `medium`, `high`, `xhigh`, or `max`; default `medium`. +- `CLAUDE_DELEGATE_MAX_BUDGET_USD`: API budget ceiling when supported by the current authentication mode. +- `CLAUDE_DELEGATE_PERMISSION_MODE`: default `auto`; prefer `plan` for read-only planning/review when tools are unnecessary. + +The helper loads project and local Claude settings while excluding user-level integrations by default, and disables browser/MCP integrations. This keeps delegation focused on the checked-out repository. If a task genuinely requires an external connector, handle that action in Codex under the original authorization rather than silently widening Claude's access. + +Never choose `bypassPermissions` merely to avoid a permission failure. Use it only when the user explicitly requests it and the execution is inside an appropriately isolated sandbox. + +For a follow-up in the same Claude session, obtain `session_id` from the JSON result and run: + +```bash +scripts/claude_delegate.sh resume SESSION_ID follow-up.md follow-up-result.json +``` + +If a call outlives the command yield, continue waiting on that same process/session rather than launching a duplicate. + +## Accept or iterate + +Claude's summary is evidence to inspect, not proof. Codex must: + +1. inspect the actual diff or artifacts; +2. run proportionate independent checks; +3. compare the result with the original scope and repository rules; +4. send a focused follow-up with concrete failures when iteration is needed; +5. report Claude's contribution separately from Codex's verification. + +Do not claim success from Claude's self-report alone. Codex retains the decision to accept, commit, publish, deploy, or make any external change. diff --git a/.codex/skills/delegate-to-claude/agents/openai.yaml b/.codex/skills/delegate-to-claude/agents/openai.yaml new file mode 100644 index 0000000..6922829 --- /dev/null +++ b/.codex/skills/delegate-to-claude/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Delegate to Claude Code" + short_description: "Delegate scoped work to Claude Code" + default_prompt: "Use $delegate-to-claude to delegate this scoped task to Claude Code and review the result." diff --git a/.codex/skills/delegate-to-claude/scripts/claude_delegate.sh b/.codex/skills/delegate-to-claude/scripts/claude_delegate.sh new file mode 100755 index 0000000..cb3b551 --- /dev/null +++ b/.codex/skills/delegate-to-claude/scripts/claude_delegate.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +set -euo pipefail + +die() { + printf 'claude_delegate: %s\n' "$*" >&2 + exit 1 +} + +usage() { + cat >&2 <<'EOF' +usage: + claude_delegate.sh check + claude_delegate.sh run [result-json] + claude_delegate.sh resume [result-json] +EOF + exit 2 +} + +command -v claude >/dev/null 2>&1 || die "claude CLI is not installed or not on PATH" + +if [[ "${1:-}" == "check" ]]; then + claude --version + auth_status="$(claude auth status 2>/dev/null)" || die "unable to read Claude authentication status" + [[ "$auth_status" == *'"loggedIn": true'* ]] || die "Claude CLI is not authenticated" + printf 'authentication: logged in\n' + exit 0 +fi + +mode="${1:-}" +case "$mode" in + run) + [[ $# -ge 2 && $# -le 3 ]] || usage + prompt_file="$2" + result_file="${3:-}" + resume_id="" + ;; + resume) + [[ $# -ge 3 && $# -le 4 ]] || usage + resume_id="$2" + prompt_file="$3" + result_file="${4:-}" + [[ "$resume_id" =~ ^[0-9a-fA-F-]{36}$ ]] || die "session id must be a UUID" + ;; + *) usage ;; +esac + +[[ -f "$prompt_file" ]] || die "prompt file does not exist: $prompt_file" +[[ -r "$prompt_file" ]] || die "prompt file is not readable: $prompt_file" + +prompt="ROLE: EXECUTOR — do the work yourself; do not spawn subagents. Stay within the work order's authorization and scope. At the end, report changed files or findings, commands and checks run with results, and any blockers. WORK ORDER: $(<"$prompt_file")" + +effort="${CLAUDE_DELEGATE_EFFORT:-medium}" +permission_mode="${CLAUDE_DELEGATE_PERMISSION_MODE:-auto}" +case "$effort" in low|medium|high|xhigh|max) ;; *) die "invalid effort: $effort" ;; esac +case "$permission_mode" in acceptEdits|auto|manual|dontAsk|plan|bypassPermissions) ;; + *) die "invalid permission mode: $permission_mode" ;; +esac + +model="${CLAUDE_DELEGATE_MODEL:-sonnet}" +args=(--print --output-format json --model "$model" --effort "$effort" --permission-mode "$permission_mode" --setting-sources project,local --strict-mcp-config --no-chrome) +[[ -n "${CLAUDE_DELEGATE_MAX_BUDGET_USD:-}" ]] && args+=(--max-budget-usd "$CLAUDE_DELEGATE_MAX_BUDGET_USD") +[[ -n "$resume_id" ]] && args+=(--resume "$resume_id") + +if [[ -n "$result_file" ]]; then + result_dir="$(dirname "$result_file")" + [[ -d "$result_dir" ]] || die "result directory does not exist: $result_dir" + claude "${args[@]}" "$prompt" | tee "$result_file" +else + claude "${args[@]}" "$prompt" +fi