Add Claude CLI integration step to plan-refine

After Oracle captures ChatGPT feedback, automatically invokes
claude -p to integrate the feedback back into the plan file.
Full iteration (ChatGPT + Claude) now runs with one command.

Use --no-integrate to skip the Claude step and get clipboard
fallback for manual integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Taylor Eernisse
2026-02-07 13:07:11 -05:00
parent defb1fb08e
commit bbf242ef44

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# plan-refine — Run one ChatGPT evaluation iteration on a plan file via Oracle # plan-refine — Run one full ChatGPT + Claude integration iteration on a plan
# Usage: plan-refine <plan-file> [options] # Usage: plan-refine <plan-file> [options]
set -euo pipefail set -euo pipefail
@@ -12,41 +12,44 @@ source "$SCRIPT_DIR/lib/frontmatter.sh"
# Defaults # Defaults
MODEL_STRATEGY="current" MODEL_STRATEGY="current"
ORACLE_MODEL="" ORACLE_MODEL=""
CLAUDE_MODEL=""
DRY_RUN=false DRY_RUN=false
SKIP_CLIPBOARD=false NO_INTEGRATE=false
BROWSER_TIMEOUT="1200s" BROWSER_TIMEOUT="1200s"
PLAN_FILE="" PLAN_FILE=""
INIT_ONLY=false
usage() { usage() {
cat <<'EOF' cat <<'EOF'
plan-refine — Send a plan to ChatGPT for adversarial review via Oracle plan-refine — One-command plan iteration: ChatGPT review + Claude integration
Usage: plan-refine <plan-file> [options] Usage: plan-refine <plan-file> [options]
After Oracle captures ChatGPT's feedback, the Claude integration Runs both steps automatically:
prompt is copied to your clipboard. Paste it into Claude Code. 1. Oracle sends plan to ChatGPT for adversarial review
2. Claude CLI integrates feedback back into the plan file
Options: Options:
--dry-run Preview prompt without sending --dry-run Preview what would run without executing
--model <model> Force Oracle model (e.g. gpt-5.2-pro) --no-integrate Only run ChatGPT step, skip Claude integration
--model <model> Force Oracle/ChatGPT model (e.g. gpt-5.2-pro)
--model-strategy <s> Browser model strategy: current|select|ignore (default: current) --model-strategy <s> Browser model strategy: current|select|ignore (default: current)
--claude-model <m> Claude model for integration (default: uses your default)
--timeout <duration> Browser timeout (default: 1200s) --timeout <duration> Browser timeout (default: 1200s)
--no-clipboard Skip copying integration prompt to clipboard --init Add plan frontmatter to file without running anything
--init Add plan frontmatter to file without running Oracle
-h, --help Show this help -h, --help Show this help
EOF EOF
exit 0 exit 0
} }
INIT_ONLY=false
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
--dry-run) DRY_RUN=true; shift ;; --dry-run) DRY_RUN=true; shift ;;
--no-integrate) NO_INTEGRATE=true; shift ;;
--model) ORACLE_MODEL="$2"; shift 2 ;; --model) ORACLE_MODEL="$2"; shift 2 ;;
--model-strategy) MODEL_STRATEGY="$2"; shift 2 ;; --model-strategy) MODEL_STRATEGY="$2"; shift 2 ;;
--claude-model) CLAUDE_MODEL="$2"; shift 2 ;;
--timeout) BROWSER_TIMEOUT="$2"; shift 2 ;; --timeout) BROWSER_TIMEOUT="$2"; shift 2 ;;
--no-clipboard) SKIP_CLIPBOARD=true; shift ;;
--init) INIT_ONLY=true; shift ;; --init) INIT_ONLY=true; shift ;;
-h|--help) usage ;; -h|--help) usage ;;
-*) echo "Unknown option: $1" >&2; exit 2 ;; -*) echo "Unknown option: $1" >&2; exit 2 ;;
@@ -93,17 +96,19 @@ NEXT_ITERATION=$((ITERATION + 1))
# Status check # Status check
if [[ "$STATUS" == "ready" || "$STATUS" == "implementing" || "$STATUS" == "completed" ]]; then if [[ "$STATUS" == "ready" || "$STATUS" == "implementing" || "$STATUS" == "completed" ]]; then
echo "Warning: Plan status is '$STATUS' already past iteration phase." echo "Warning: Plan status is '$STATUS' -- already past iteration phase."
echo "Continue anyway? (y/N)" echo "Continue anyway? (y/N)"
read -r confirm read -r confirm
[[ "$confirm" != "y" && "$confirm" != "Y" ]] && exit 0 [[ "$confirm" != "y" && "$confirm" != "Y" ]] && exit 0
fi fi
# Build feedback output path # Build paths
FEEDBACK_FILE="${PLAN_FILE%.md}.feedback-${NEXT_ITERATION}.md" FEEDBACK_FILE="${PLAN_FILE%.md}.feedback-${NEXT_ITERATION}.md"
PLAN_DIR=$(dirname "$PLAN_FILE")
# Read evaluation prompt # Read prompts
EVAL_PROMPT=$(cat "$PROMPTS_DIR/chatgpt-eval.md") EVAL_PROMPT=$(cat "$PROMPTS_DIR/chatgpt-eval.md")
INTEGRATE_PROMPT=$(cat "$PROMPTS_DIR/claude-integrate.md")
# Build Oracle model args # Build Oracle model args
ORACLE_MODEL_ARGS=() ORACLE_MODEL_ARGS=()
@@ -111,35 +116,62 @@ if [[ -n "$ORACLE_MODEL" ]]; then
ORACLE_MODEL_ARGS+=(--model "$ORACLE_MODEL") ORACLE_MODEL_ARGS+=(--model "$ORACLE_MODEL")
fi fi
# Build Claude model args
CLAUDE_MODEL_ARGS=()
if [[ -n "$CLAUDE_MODEL" ]]; then
CLAUDE_MODEL_ARGS+=(--model "$CLAUDE_MODEL")
fi
echo "=== plan-refine ===" echo "=== plan-refine ==="
echo " Plan: $(basename "$PLAN_FILE")" echo " Plan: $(basename "$PLAN_FILE")"
echo " Status: $STATUS" echo " Status: $STATUS"
echo " Iteration: $ITERATION -> $NEXT_ITERATION (target: $TARGET)" echo " Iteration: $ITERATION -> $NEXT_ITERATION (target: $TARGET)"
echo " Feedback: $(basename "$FEEDBACK_FILE")" echo " Feedback: $(basename "$FEEDBACK_FILE")"
if [[ "$NO_INTEGRATE" == "true" ]]; then
echo " Mode: ChatGPT review only (--no-integrate)"
else
echo " Mode: Full cycle (ChatGPT review + Claude integration)"
fi
echo "" echo ""
if [[ "$DRY_RUN" == "true" ]]; then if [[ "$DRY_RUN" == "true" ]]; then
echo "=== DRY RUN — would send this to Oracle ===" echo "=== DRY RUN ==="
echo "" echo ""
echo "Step 1: Oracle -> ChatGPT"
echo " oracle --engine browser \\" echo " oracle --engine browser \\"
echo " --browser-manual-login \\" echo " --browser-manual-login \\"
echo " --browser-model-strategy $MODEL_STRATEGY \\" echo " --browser-model-strategy $MODEL_STRATEGY \\"
echo " --browser-timeout $BROWSER_TIMEOUT \\" echo " --browser-timeout $BROWSER_TIMEOUT \\"
[[ -n "$ORACLE_MODEL" ]] && echo " --model $ORACLE_MODEL \\" [[ -n "$ORACLE_MODEL" ]] && echo " --model $ORACLE_MODEL \\"
echo " -p \"$(echo "$EVAL_PROMPT" | head -1)...\" \\" echo " -p \"$(echo "$EVAL_PROMPT" | head -c 80)...\" \\"
echo " --file \"$PLAN_FILE\" \\" echo " --file \"$PLAN_FILE\" \\"
echo " --write-output \"$FEEDBACK_FILE\"" echo " --write-output \"$FEEDBACK_FILE\""
echo "" echo ""
echo "=== FULL PROMPT ===" if [[ "$NO_INTEGRATE" != "true" ]]; then
echo "Step 2: Claude CLI -> Integration"
echo " claude -p <integration-prompt> \\"
echo " --allowedTools \"Read,Edit,Write\" \\"
echo " --permission-mode acceptEdits \\"
echo " --add-dir \"$PLAN_DIR\""
[[ -n "$CLAUDE_MODEL" ]] && echo " --model $CLAUDE_MODEL"
fi
echo ""
echo "=== ChatGPT PROMPT ==="
echo "$EVAL_PROMPT" echo "$EVAL_PROMPT"
echo ""
echo "=== Claude INTEGRATION PROMPT ==="
echo "$INTEGRATE_PROMPT"
exit 0 exit 0
fi fi
echo "Sending to ChatGPT via Oracle..." # ──────────────────────────────────────────────
echo "(This may take a few minutes. Oracle will automate the browser.)" # Step 1: ChatGPT evaluation via Oracle
# ──────────────────────────────────────────────
echo "[Step 1/2] Sending to ChatGPT via Oracle..."
echo "(Oracle will automate the browser. This may take a few minutes.)"
echo "" echo ""
# Call Oracle
oracle --engine browser \ oracle --engine browser \
--browser-manual-login \ --browser-manual-login \
--browser-model-strategy "$MODEL_STRATEGY" \ --browser-model-strategy "$MODEL_STRATEGY" \
@@ -161,21 +193,16 @@ if [[ ! -f "$FEEDBACK_FILE" ]]; then
exit 1 exit 1
fi fi
# Update frontmatter
set_frontmatter "$PLAN_FILE" "iteration" "$NEXT_ITERATION"
set_frontmatter "$PLAN_FILE" "updated" "$(date +%Y-%m-%d)"
if [[ "$STATUS" == "drafting" ]]; then
set_frontmatter "$PLAN_FILE" "status" "iterating"
fi
echo ""
echo "Feedback saved to: $FEEDBACK_FILE"
echo "" echo ""
echo "ChatGPT feedback saved to: $FEEDBACK_FILE"
# Build and copy Claude integration prompt # ──────────────────────────────────────────────
if [[ "$SKIP_CLIPBOARD" != "true" ]] && command -v pbcopy &>/dev/null; then # Step 2: Claude integration
INTEGRATE_PROMPT=$(cat "$PROMPTS_DIR/claude-integrate.md") # ──────────────────────────────────────────────
if [[ "$NO_INTEGRATE" == "true" ]]; then
# Clipboard fallback for manual integration
if command -v pbcopy &>/dev/null; then
CLIPBOARD_CONTENT="Read the plan at: $PLAN_FILE CLIPBOARD_CONTENT="Read the plan at: $PLAN_FILE
Read ChatGPT's feedback at: $FEEDBACK_FILE Read ChatGPT's feedback at: $FEEDBACK_FILE
@@ -184,17 +211,62 @@ ${INTEGRATE_PROMPT}
Write the updated plan back to: $PLAN_FILE" Write the updated plan back to: $PLAN_FILE"
echo "$CLIPBOARD_CONTENT" | pbcopy echo "$CLIPBOARD_CONTENT" | pbcopy
echo "Claude integration prompt copied to clipboard." echo ""
echo "Paste it into Claude Code to integrate the feedback." echo "Integration prompt copied to clipboard. Paste into Claude Code."
else else
echo "Next: Tell Claude to integrate the feedback." echo ""
echo "Skipped integration. Run manually:"
echo " Plan: $PLAN_FILE" echo " Plan: $PLAN_FILE"
echo " Feedback: $FEEDBACK_FILE" echo " Feedback: $FEEDBACK_FILE"
fi fi
else
echo ""
echo "[Step 2/2] Claude integrating feedback into plan..."
CLAUDE_PROMPT="Read the original plan at: ${PLAN_FILE}
Read ChatGPT's feedback at: ${FEEDBACK_FILE}
${INTEGRATE_PROMPT}
Important instructions:
- Write the updated plan back to: ${PLAN_FILE}
- Preserve the YAML frontmatter block (between the --- delimiters) at the top unchanged.
- Only modify the content below the frontmatter.
- Do NOT output the plan to stdout. Write it directly to the file."
claude -p "$CLAUDE_PROMPT" \
--allowedTools "Read,Edit,Write" \
--permission-mode acceptEdits \
--add-dir "$PLAN_DIR" \
"${CLAUDE_MODEL_ARGS[@]}"
CLAUDE_EXIT=$?
if [[ $CLAUDE_EXIT -ne 0 ]]; then
echo "Error: Claude CLI exited with code $CLAUDE_EXIT" >&2
echo "Feedback is still available at: $FEEDBACK_FILE"
echo "You can integrate manually in Claude Code."
exit $CLAUDE_EXIT
fi
echo "Integration complete. Plan updated."
fi
# ──────────────────────────────────────────────
# Update frontmatter
# ──────────────────────────────────────────────
set_frontmatter "$PLAN_FILE" "iteration" "$NEXT_ITERATION"
set_frontmatter "$PLAN_FILE" "updated" "$(date +%Y-%m-%d)"
if [[ "$STATUS" == "drafting" ]]; then
set_frontmatter "$PLAN_FILE" "status" "iterating"
fi
echo ""
echo "=== Iteration $NEXT_ITERATION/$TARGET complete ==="
# Progress indicator
if [[ $NEXT_ITERATION -ge $TARGET ]]; then if [[ $NEXT_ITERATION -ge $TARGET ]]; then
echo "" echo ""
echo "Target iterations reached ($NEXT_ITERATION/$TARGET)." echo "Target iterations reached. Plan may be ready for bead splitting."
echo "Consider: plan-refine $PLAN_FILE --init (to update status to 'splitting')" echo "To advance status: set 'status: splitting' in the frontmatter."
fi fi