diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 0540187..08bb3d6 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -10,7 +10,7 @@ "name": "agent-loop", "source": "./", "description": "Autonomous generator-evaluator agent loop for long-running coding tasks. Plan interactively, then execute with full visibility.", - "version": "0.9.0", + "version": "0.10.0", "author": { "name": "Sheldon" }, diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index b4b1971..b446e57 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agent-loop", - "version": "0.9.0", + "version": "0.10.0", "description": "Autonomous generator-evaluator agent loop for long-running coding tasks. Run /agent-loop:run to start.", "author": { "name": "Sheldon" diff --git a/setup.sh b/setup.sh index 1e05fa9..7eebcec 100755 --- a/setup.sh +++ b/setup.sh @@ -10,10 +10,17 @@ set -euo pipefail +# --- Parse arguments --- +UPDATE_ONLY=false MODE="${1:-implement}" +if [ "$MODE" = "--update" ]; then + UPDATE_ONLY=true + MODE="${2:-implement}" # mode not used in update, but keep arg parsing clean +fi + # --- Validate mode --- -if [[ ! "$MODE" =~ ^(implement|explore|fix)$ ]]; then +if [ "$UPDATE_ONLY" = false ] && [[ ! "$MODE" =~ ^(implement|explore|fix)$ ]]; then echo "[setup] ERROR: Invalid mode '$MODE'. Must be: implement, explore, fix" exit 1 fi @@ -45,6 +52,37 @@ fi echo "[setup] Harness source: $HARNESS_SRC" +# Read plugin version from source +PLUGIN_VERSION="" +if [ -f "$HARNESS_SRC/.claude-plugin/plugin.json" ]; then + if command -v jq &>/dev/null; then + PLUGIN_VERSION=$(jq -r '.version // empty' "$HARNESS_SRC/.claude-plugin/plugin.json" 2>/dev/null) + elif command -v python3 &>/dev/null; then + PLUGIN_VERSION=$(python3 -c "import json; print(json.load(open('$HARNESS_SRC/.claude-plugin/plugin.json')).get('version',''),end='')" 2>/dev/null) + fi +fi + +# --- Update-only mode: refresh harness files without touching run state --- +if [ "$UPDATE_ONLY" = true ]; then + LOOP_DIR="$(pwd)/.loop" + if [ ! -d "$LOOP_DIR" ]; then + echo "[setup] ERROR: No .loop/ directory found. Run setup first." + exit 1 + fi + + echo "[setup] Updating harness files..." + cp -r "$HARNESS_SRC/prompts" "$LOOP_DIR/" + cp -r "$HARNESS_SRC/templates" "$LOOP_DIR/" + cp -r "$HARNESS_SRC/lib" "$LOOP_DIR/" + cp "$HARNESS_SRC/loop.sh" "$LOOP_DIR/" + chmod +x "$LOOP_DIR/loop.sh" + + [ -n "$PLUGIN_VERSION" ] && echo "$PLUGIN_VERSION" > "$LOOP_DIR/.harness-version" + + echo "[setup] Harness updated to ${PLUGIN_VERSION:-unknown}. Run state (prd.json, contracts, config.json) unchanged." + exit 0 +fi + # --- Ensure git repo exists --- if ! git rev-parse --git-dir &>/dev/null; then echo "[setup] No git repo found. Initializing..." @@ -79,6 +117,9 @@ cp -r "$HARNESS_SRC/lib" "$LOOP_DIR/" cp "$HARNESS_SRC/loop.sh" "$LOOP_DIR/" chmod +x "$LOOP_DIR/loop.sh" +# Stamp harness version +[ -n "$PLUGIN_VERSION" ] && echo "$PLUGIN_VERSION" > "$LOOP_DIR/.harness-version" + # Verify critical files for f in prompts/generator/_base.md prompts/evaluator/_base.md templates/progress.md.template lib/state.sh loop.sh; do if [ ! -f "$LOOP_DIR/$f" ]; then @@ -99,6 +140,7 @@ triage/ archive/ .archive-staging/ .last-branch +.harness-version .loop.lock GITIGNORE diff --git a/skills/run/SKILL.md b/skills/run/SKILL.md index 142d0ff..6bfb9bc 100644 --- a/skills/run/SKILL.md +++ b/skills/run/SKILL.md @@ -20,7 +20,7 @@ Follow this sequence. Each phase checks what exists and skips if already done. --- -## Phase 1: Scaffold (if needed) +## Phase 1: Scaffold or Update Harness Check if `.loop/config.json` exists. @@ -36,7 +36,23 @@ bash "$(ls -d ~/.claude/plugins/cache/agent-loop/agent-loop/*/setup.sh 2>/dev/nu Show the output. If setup fails, stop. -**If it already exists**, skip to Phase 2. +**If it already exists**, check if the harness files need updating. Compare the installed harness version against the plugin version: + +```bash +INSTALLED=$(cat .loop/.harness-version 2>/dev/null || echo "unknown") +PLUGIN=$(jq -r '.version // empty' "$(ls -d ~/.claude/plugins/cache/agent-loop/agent-loop/*/.claude-plugin/plugin.json 2>/dev/null | tail -1)" 2>/dev/null || echo "unknown") +echo "installed=$INSTALLED plugin=$PLUGIN" +``` + +If the versions differ (or installed is "unknown"), update the harness files: + +```bash +bash "$(ls -d ~/.claude/plugins/cache/agent-loop/agent-loop/*/setup.sh 2>/dev/null | tail -1)" --update +``` + +Tell the user: *"Updated harness files to v{version}."* Then continue to Phase 2. + +If versions match, skip to Phase 2. ---