Rewrite plan-refine for clipboard-based workflow
Oracle browser automation has macOS Keychain issues that prevent cookie-based auth. Replaced with a two-command clipboard workflow: plan-refine <file> # copies ChatGPT prompt to clipboard plan-refine <file> --integrate # Claude CLI integrates feedback Step 1 uses Oracle --render --copy (no browser needed) to bundle the evaluation prompt with plan content. Step 2 uses claude -p for headless integration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
302
bin/plan-refine
302
bin/plan-refine
@@ -1,6 +1,10 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# plan-refine — Run one full ChatGPT + Claude integration iteration on a plan
|
# plan-refine — One-command plan iteration: ChatGPT review + Claude integration
|
||||||
# Usage: plan-refine <plan-file> [options]
|
# Usage: plan-refine <plan-file> [options]
|
||||||
|
#
|
||||||
|
# Step 1: Assembles evaluation prompt + plan content, copies to clipboard.
|
||||||
|
# User pastes into ChatGPT, copies response, saves to feedback file.
|
||||||
|
# Step 2: Claude CLI integrates feedback back into the plan file.
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -17,32 +21,29 @@ PROMPTS_DIR="$SCRIPT_DIR/prompts"
|
|||||||
source "$SCRIPT_DIR/lib/frontmatter.sh"
|
source "$SCRIPT_DIR/lib/frontmatter.sh"
|
||||||
|
|
||||||
# Defaults
|
# Defaults
|
||||||
MODEL_STRATEGY="current"
|
|
||||||
ORACLE_MODEL=""
|
|
||||||
CLAUDE_MODEL=""
|
CLAUDE_MODEL=""
|
||||||
DRY_RUN=false
|
DRY_RUN=false
|
||||||
NO_INTEGRATE=false
|
NO_INTEGRATE=false
|
||||||
BROWSER_TIMEOUT="1200s"
|
|
||||||
PLAN_FILE=""
|
PLAN_FILE=""
|
||||||
INIT_ONLY=false
|
INIT_ONLY=false
|
||||||
|
STEP=""
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
plan-refine — One-command plan iteration: ChatGPT review + Claude integration
|
plan-refine — Semi-automated plan iteration: ChatGPT review + Claude integration
|
||||||
|
|
||||||
Usage: plan-refine <plan-file> [options]
|
Usage: plan-refine <plan-file> [options]
|
||||||
|
|
||||||
Runs both steps automatically:
|
Workflow per iteration:
|
||||||
1. Oracle sends plan to ChatGPT for adversarial review
|
1. plan-refine <file> Copies ChatGPT prompt to clipboard
|
||||||
2. Claude CLI integrates feedback back into the plan file
|
2. Paste into ChatGPT, copy response, save to <file>.feedback-N.md
|
||||||
|
3. plan-refine <file> --integrate Claude integrates feedback into plan
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--dry-run Preview what would run without executing
|
--integrate Run Claude integration (Step 2)
|
||||||
--no-integrate Only run ChatGPT step, skip Claude integration
|
--no-integrate Skip Claude integration, just update frontmatter
|
||||||
--model <model> Force Oracle/ChatGPT model (e.g. gpt-5.2-pro)
|
--claude-model <m> Claude model for integration (default: your default)
|
||||||
--model-strategy <s> Browser model strategy: current|select|ignore (default: current)
|
--dry-run Preview what would happen
|
||||||
--claude-model <m> Claude model for integration (default: uses your default)
|
|
||||||
--timeout <duration> Browser timeout (default: 1200s)
|
|
||||||
--init Add plan frontmatter to file without running anything
|
--init Add plan frontmatter to file without running anything
|
||||||
-h, --help Show this help
|
-h, --help Show this help
|
||||||
EOF
|
EOF
|
||||||
@@ -51,12 +52,10 @@ EOF
|
|||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--dry-run) DRY_RUN=true; shift ;;
|
--integrate) STEP="integrate"; shift ;;
|
||||||
--no-integrate) NO_INTEGRATE=true; shift ;;
|
--no-integrate) NO_INTEGRATE=true; shift ;;
|
||||||
--model) ORACLE_MODEL="$2"; shift 2 ;;
|
--dry-run) DRY_RUN=true; shift ;;
|
||||||
--model-strategy) MODEL_STRATEGY="$2"; shift 2 ;;
|
|
||||||
--claude-model) CLAUDE_MODEL="$2"; shift 2 ;;
|
--claude-model) CLAUDE_MODEL="$2"; shift 2 ;;
|
||||||
--timeout) BROWSER_TIMEOUT="$2"; shift 2 ;;
|
|
||||||
--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 ;;
|
||||||
@@ -100,6 +99,14 @@ ITERATION=$(get_frontmatter "$PLAN_FILE" "iteration" "0")
|
|||||||
TARGET=$(get_frontmatter "$PLAN_FILE" "target_iterations" "8")
|
TARGET=$(get_frontmatter "$PLAN_FILE" "target_iterations" "8")
|
||||||
STATUS=$(get_frontmatter "$PLAN_FILE" "status" "drafting")
|
STATUS=$(get_frontmatter "$PLAN_FILE" "status" "drafting")
|
||||||
NEXT_ITERATION=$((ITERATION + 1))
|
NEXT_ITERATION=$((ITERATION + 1))
|
||||||
|
PLAN_DIR=$(dirname "$PLAN_FILE")
|
||||||
|
|
||||||
|
# Build paths
|
||||||
|
FEEDBACK_FILE="${PLAN_FILE%.md}.feedback-${NEXT_ITERATION}.md"
|
||||||
|
|
||||||
|
# Read prompts
|
||||||
|
EVAL_PROMPT=$(cat "$PROMPTS_DIR/chatgpt-eval.md")
|
||||||
|
INTEGRATE_PROMPT=$(cat "$PROMPTS_DIR/claude-integrate.md")
|
||||||
|
|
||||||
# Status check
|
# Status check
|
||||||
if [[ "$STATUS" == "ready" || "$STATUS" == "implementing" || "$STATUS" == "completed" ]]; then
|
if [[ "$STATUS" == "ready" || "$STATUS" == "implementing" || "$STATUS" == "completed" ]]; then
|
||||||
@@ -109,129 +116,56 @@ if [[ "$STATUS" == "ready" || "$STATUS" == "implementing" || "$STATUS" == "compl
|
|||||||
[[ "$confirm" != "y" && "$confirm" != "Y" ]] && exit 0
|
[[ "$confirm" != "y" && "$confirm" != "Y" ]] && exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Build paths
|
# ──────────────────────────────────────────────
|
||||||
FEEDBACK_FILE="${PLAN_FILE%.md}.feedback-${NEXT_ITERATION}.md"
|
# Route to the right step
|
||||||
PLAN_DIR=$(dirname "$PLAN_FILE")
|
# ──────────────────────────────────────────────
|
||||||
|
|
||||||
# Read prompts
|
if [[ "$STEP" == "integrate" ]]; then
|
||||||
EVAL_PROMPT=$(cat "$PROMPTS_DIR/chatgpt-eval.md")
|
# ──────────────────────────────────────────
|
||||||
INTEGRATE_PROMPT=$(cat "$PROMPTS_DIR/claude-integrate.md")
|
# Step 2: Claude integration
|
||||||
|
# ──────────────────────────────────────────
|
||||||
|
|
||||||
# Build Oracle model args
|
# Find the latest feedback file
|
||||||
ORACLE_MODEL_ARGS=()
|
if [[ -f "$FEEDBACK_FILE" ]]; then
|
||||||
if [[ -n "$ORACLE_MODEL" ]]; then
|
FOUND_FEEDBACK="$FEEDBACK_FILE"
|
||||||
ORACLE_MODEL_ARGS+=(--model "$ORACLE_MODEL")
|
else
|
||||||
fi
|
# Search for any feedback file for the current iteration
|
||||||
|
FOUND_FEEDBACK=$(ls -t "${PLAN_FILE%.md}".feedback-*.md 2>/dev/null | head -1)
|
||||||
|
fi
|
||||||
|
|
||||||
# Build Claude model args
|
if [[ -z "$FOUND_FEEDBACK" || ! -f "$FOUND_FEEDBACK" ]]; then
|
||||||
CLAUDE_MODEL_ARGS=()
|
echo "Error: No feedback file found." >&2
|
||||||
if [[ -n "$CLAUDE_MODEL" ]]; then
|
echo "Expected: $FEEDBACK_FILE" >&2
|
||||||
CLAUDE_MODEL_ARGS+=(--model "$CLAUDE_MODEL")
|
echo "" >&2
|
||||||
fi
|
echo "Run step 1 first: plan-refine $PLAN_FILE" >&2
|
||||||
|
echo "Then save ChatGPT's response to: $FEEDBACK_FILE" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo "=== plan-refine ==="
|
echo "=== plan-refine --integrate ==="
|
||||||
echo " Plan: $(basename "$PLAN_FILE")"
|
echo " Plan: $(basename "$PLAN_FILE")"
|
||||||
echo " Status: $STATUS"
|
echo " Feedback: $(basename "$FOUND_FEEDBACK")"
|
||||||
echo " Iteration: $ITERATION -> $NEXT_ITERATION (target: $TARGET)"
|
echo " Iteration: $ITERATION -> $NEXT_ITERATION (target: $TARGET)"
|
||||||
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 ""
|
|
||||||
|
|
||||||
if [[ "$DRY_RUN" == "true" ]]; then
|
|
||||||
echo "=== DRY RUN ==="
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Step 1: Oracle -> ChatGPT"
|
|
||||||
echo " oracle --engine browser \\"
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
echo " --browser-manual-login \\"
|
echo "=== DRY RUN ==="
|
||||||
echo " --browser-model-strategy $MODEL_STRATEGY \\"
|
echo "Would run:"
|
||||||
echo " --browser-timeout $BROWSER_TIMEOUT \\"
|
|
||||||
[[ -n "$ORACLE_MODEL" ]] && echo " --model $ORACLE_MODEL \\"
|
|
||||||
echo " -p \"$(echo "$EVAL_PROMPT" | head -c 80)...\" \\"
|
|
||||||
echo " --file \"$PLAN_FILE\" \\"
|
|
||||||
echo " --write-output \"$FEEDBACK_FILE\""
|
|
||||||
echo ""
|
|
||||||
if [[ "$NO_INTEGRATE" != "true" ]]; then
|
|
||||||
echo "Step 2: Claude CLI -> Integration"
|
|
||||||
echo " claude -p <integration-prompt> \\"
|
echo " claude -p <integration-prompt> \\"
|
||||||
echo " --allowedTools \"Read,Edit,Write\" \\"
|
echo " --allowedTools \"Read,Edit,Write\" \\"
|
||||||
echo " --permission-mode acceptEdits \\"
|
echo " --permission-mode acceptEdits \\"
|
||||||
echo " --add-dir \"$PLAN_DIR\""
|
echo " --add-dir \"$PLAN_DIR\""
|
||||||
[[ -n "$CLAUDE_MODEL" ]] && echo " --model $CLAUDE_MODEL"
|
[[ -n "$CLAUDE_MODEL" ]] && echo " --model $CLAUDE_MODEL"
|
||||||
|
exit 0
|
||||||
fi
|
fi
|
||||||
echo ""
|
|
||||||
echo "=== ChatGPT PROMPT ==="
|
|
||||||
echo "$EVAL_PROMPT"
|
|
||||||
echo ""
|
|
||||||
echo "=== Claude INTEGRATION PROMPT ==="
|
|
||||||
echo "$INTEGRATE_PROMPT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ──────────────────────────────────────────────
|
if [[ "$NO_INTEGRATE" == "true" ]]; then
|
||||||
# Step 1: ChatGPT evaluation via Oracle
|
echo "Skipping Claude integration (--no-integrate)."
|
||||||
# ──────────────────────────────────────────────
|
|
||||||
|
|
||||||
echo "[Step 1/2] Sending to ChatGPT via Oracle..."
|
|
||||||
echo "(Oracle will automate the browser. This may take a few minutes.)"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
oracle --engine browser \
|
|
||||||
--browser-manual-login \
|
|
||||||
--browser-model-strategy "$MODEL_STRATEGY" \
|
|
||||||
--browser-timeout "$BROWSER_TIMEOUT" \
|
|
||||||
"${ORACLE_MODEL_ARGS[@]}" \
|
|
||||||
-p "$EVAL_PROMPT" \
|
|
||||||
--file "$PLAN_FILE" \
|
|
||||||
--write-output "$FEEDBACK_FILE"
|
|
||||||
|
|
||||||
ORACLE_EXIT=$?
|
|
||||||
|
|
||||||
if [[ $ORACLE_EXIT -ne 0 ]]; then
|
|
||||||
echo "Error: Oracle exited with code $ORACLE_EXIT" >&2
|
|
||||||
exit $ORACLE_EXIT
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -f "$FEEDBACK_FILE" ]]; then
|
|
||||||
echo "Error: Expected feedback file not found: $FEEDBACK_FILE" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "ChatGPT feedback saved to: $FEEDBACK_FILE"
|
|
||||||
|
|
||||||
# ──────────────────────────────────────────────
|
|
||||||
# Step 2: Claude integration
|
|
||||||
# ──────────────────────────────────────────────
|
|
||||||
|
|
||||||
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
|
|
||||||
Read ChatGPT's feedback at: $FEEDBACK_FILE
|
|
||||||
|
|
||||||
${INTEGRATE_PROMPT}
|
|
||||||
|
|
||||||
Write the updated plan back to: $PLAN_FILE"
|
|
||||||
|
|
||||||
echo "$CLIPBOARD_CONTENT" | pbcopy
|
|
||||||
echo ""
|
|
||||||
echo "Integration prompt copied to clipboard. Paste into Claude Code."
|
|
||||||
else
|
else
|
||||||
echo ""
|
echo "Claude integrating feedback into plan..."
|
||||||
echo "Skipped integration. Run manually:"
|
|
||||||
echo " Plan: $PLAN_FILE"
|
|
||||||
echo " Feedback: $FEEDBACK_FILE"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
echo "[Step 2/2] Claude integrating feedback into plan..."
|
|
||||||
|
|
||||||
CLAUDE_PROMPT="Read the original plan at: ${PLAN_FILE}
|
CLAUDE_PROMPT="Read the original plan at: ${PLAN_FILE}
|
||||||
Read ChatGPT's feedback at: ${FEEDBACK_FILE}
|
Read ChatGPT's feedback at: ${FOUND_FEEDBACK}
|
||||||
|
|
||||||
${INTEGRATE_PROMPT}
|
${INTEGRATE_PROMPT}
|
||||||
|
|
||||||
@@ -241,39 +175,95 @@ Important instructions:
|
|||||||
- Only modify the content below the frontmatter.
|
- Only modify the content below the frontmatter.
|
||||||
- Do NOT output the plan to stdout. Write it directly to the file."
|
- Do NOT output the plan to stdout. Write it directly to the file."
|
||||||
|
|
||||||
claude -p "$CLAUDE_PROMPT" \
|
CLAUDE_MODEL_ARGS=()
|
||||||
--allowedTools "Read,Edit,Write" \
|
if [[ -n "$CLAUDE_MODEL" ]]; then
|
||||||
--permission-mode acceptEdits \
|
CLAUDE_MODEL_ARGS+=(--model "$CLAUDE_MODEL")
|
||||||
--add-dir "$PLAN_DIR" \
|
fi
|
||||||
"${CLAUDE_MODEL_ARGS[@]}"
|
|
||||||
|
|
||||||
CLAUDE_EXIT=$?
|
claude -p "$CLAUDE_PROMPT" \
|
||||||
|
--allowedTools "Read,Edit,Write" \
|
||||||
|
--permission-mode acceptEdits \
|
||||||
|
--add-dir "$PLAN_DIR" \
|
||||||
|
"${CLAUDE_MODEL_ARGS[@]}"
|
||||||
|
|
||||||
if [[ $CLAUDE_EXIT -ne 0 ]]; then
|
CLAUDE_EXIT=$?
|
||||||
echo "Error: Claude CLI exited with code $CLAUDE_EXIT" >&2
|
|
||||||
echo "Feedback is still available at: $FEEDBACK_FILE"
|
if [[ $CLAUDE_EXIT -ne 0 ]]; then
|
||||||
echo "You can integrate manually in Claude Code."
|
echo "Error: Claude CLI exited with code $CLAUDE_EXIT" >&2
|
||||||
exit $CLAUDE_EXIT
|
echo "Feedback is still available at: $FOUND_FEEDBACK" >&2
|
||||||
|
echo "You can integrate manually in Claude Code." >&2
|
||||||
|
exit $CLAUDE_EXIT
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Integration complete. Plan updated."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Integration complete. Plan updated."
|
# Update frontmatter
|
||||||
fi
|
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
|
||||||
|
|
||||||
# ──────────────────────────────────────────────
|
|
||||||
# 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 ==="
|
|
||||||
|
|
||||||
if [[ $NEXT_ITERATION -ge $TARGET ]]; then
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Target iterations reached. Plan may be ready for bead splitting."
|
echo "=== Iteration $NEXT_ITERATION/$TARGET complete ==="
|
||||||
echo "To advance status: set 'status: splitting' in the frontmatter."
|
|
||||||
|
if [[ $NEXT_ITERATION -ge $TARGET ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "Target iterations reached. Plan may be ready for bead splitting."
|
||||||
|
echo "To advance status: set 'status: splitting' in the frontmatter."
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
# ──────────────────────────────────────────
|
||||||
|
# Step 1: Prepare ChatGPT prompt
|
||||||
|
# ──────────────────────────────────────────
|
||||||
|
|
||||||
|
echo "=== plan-refine ==="
|
||||||
|
echo " Plan: $(basename "$PLAN_FILE")"
|
||||||
|
echo " Status: $STATUS"
|
||||||
|
echo " Iteration: $ITERATION -> $NEXT_ITERATION (target: $TARGET)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Use Oracle's --render --copy to bundle prompt + file content
|
||||||
|
if command -v oracle &>/dev/null; then
|
||||||
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
|
echo "=== DRY RUN ==="
|
||||||
|
echo "Would run: oracle --render --copy -p <eval-prompt> --file $PLAN_FILE"
|
||||||
|
echo ""
|
||||||
|
echo "=== PROMPT ==="
|
||||||
|
echo "$EVAL_PROMPT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
oracle --render --copy \
|
||||||
|
-p "$EVAL_PROMPT" \
|
||||||
|
--file "$PLAN_FILE" 2>/dev/null
|
||||||
|
|
||||||
|
echo "ChatGPT prompt copied to clipboard (assembled by Oracle)."
|
||||||
|
else
|
||||||
|
# Fallback: manual clipboard assembly
|
||||||
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
|
echo "=== DRY RUN ==="
|
||||||
|
echo "Would copy evaluation prompt + plan content to clipboard."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
PLAN_CONTENT=$(cat "$PLAN_FILE")
|
||||||
|
CLIPBOARD="${EVAL_PROMPT}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
${PLAN_CONTENT}"
|
||||||
|
echo "$CLIPBOARD" | pbcopy
|
||||||
|
echo "ChatGPT prompt copied to clipboard."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " 1. Paste into ChatGPT (Cmd+V)"
|
||||||
|
echo " 2. Wait for response"
|
||||||
|
echo " 3. Copy ChatGPT's full response"
|
||||||
|
echo " 4. Save it to: $FEEDBACK_FILE"
|
||||||
|
echo " 5. Run: plan-refine $(basename "$PLAN_FILE") --integrate"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user