feat: agent loop harness with Claude Code plugin support
Generator-evaluator architecture with iterative context-reset for long-running coding tasks. Ships as a Claude Code plugin — install with /plugin and use /agent-loop:init, /agent-loop:plan, /agent-loop:run.
This commit is contained in:
83
lib/archive.sh
Normal file
83
lib/archive.sh
Normal file
@@ -0,0 +1,83 @@
|
||||
#!/bin/bash
|
||||
# Branch archiving — archives previous run artifacts when the branch changes.
|
||||
# Preserves prd.json, progress.md, and contracts from the previous feature.
|
||||
#
|
||||
# Design: At the end of each run, snapshot_for_archive saves current artifacts
|
||||
# to .archive-staging/. On the next run, if the branch changed, check_archive
|
||||
# moves the snapshot to archive/ and cleans up. This avoids archiving the
|
||||
# WRONG artifacts (the new feature's) when prd.json has already been overwritten.
|
||||
|
||||
LAST_BRANCH_FILE="$LOOP_DIR/.last-branch"
|
||||
STAGING_DIR="$LOOP_DIR/.archive-staging"
|
||||
|
||||
# Snapshot current artifacts so they can be archived later if the branch changes.
|
||||
# Call this at the END of a successful run or before exit.
|
||||
snapshot_for_archive() {
|
||||
rm -rf "$STAGING_DIR"
|
||||
mkdir -p "$STAGING_DIR"
|
||||
|
||||
[ -f "$LOOP_DIR/prd.json" ] && cp "$LOOP_DIR/prd.json" "$STAGING_DIR/"
|
||||
[ -f "$LOOP_DIR/progress.md" ] && cp "$LOOP_DIR/progress.md" "$STAGING_DIR/"
|
||||
[ -d "$LOOP_DIR/contracts" ] && cp -r "$LOOP_DIR/contracts" "$STAGING_DIR/"
|
||||
}
|
||||
|
||||
# Check if we need to archive and do so if branch changed.
|
||||
# Reads the NEW branch from live prd.json and the OLD branch from the staging
|
||||
# snapshot (which was saved at the end of the previous run). This avoids the
|
||||
# bug where both branches read from the same (already-overwritten) prd.json.
|
||||
check_archive() {
|
||||
local current_branch
|
||||
current_branch=$(prd_branch_name 2>/dev/null)
|
||||
[ -z "$current_branch" ] && return
|
||||
|
||||
# Determine the previous branch from the staging snapshot (most reliable)
|
||||
# or fall back to .last-branch file
|
||||
local last_branch=""
|
||||
if [ -f "$STAGING_DIR/prd.json" ]; then
|
||||
if command -v jq &>/dev/null; then
|
||||
last_branch=$(jq -r '.branchName // empty' "$STAGING_DIR/prd.json" 2>/dev/null)
|
||||
else
|
||||
last_branch=$(LOOP_PRD="$STAGING_DIR/prd.json" python3 -c "
|
||||
import json, os
|
||||
print(json.load(open(os.environ['LOOP_PRD'])).get('branchName', ''), end='')
|
||||
" 2>/dev/null)
|
||||
fi
|
||||
fi
|
||||
[ -z "$last_branch" ] && [ -f "$LAST_BRANCH_FILE" ] && last_branch=$(cat "$LAST_BRANCH_FILE")
|
||||
|
||||
if [ -n "$last_branch" ] && [ "$last_branch" != "$current_branch" ]; then
|
||||
archive_run "$last_branch"
|
||||
fi
|
||||
|
||||
echo "$current_branch" > "$LAST_BRANCH_FILE"
|
||||
}
|
||||
|
||||
# Archive the previous run's staged artifacts (NOT current prd.json)
|
||||
archive_run() {
|
||||
local branch_name="$1"
|
||||
local feature_name
|
||||
feature_name=$(echo "$branch_name" | sed 's|.*/||')
|
||||
|
||||
local archive_dir="$LOOP_DIR/archive/$(date +%Y-%m-%d)-${feature_name}"
|
||||
mkdir -p "$archive_dir"
|
||||
|
||||
if [ -d "$STAGING_DIR" ]; then
|
||||
# Use the staged snapshot (correct artifacts from the previous run)
|
||||
cp -r "$STAGING_DIR"/* "$archive_dir/" 2>/dev/null || true
|
||||
rm -rf "$STAGING_DIR"
|
||||
else
|
||||
# Fallback: no snapshot exists (first run or upgrade from old version).
|
||||
# Current artifacts may belong to the new feature — archive what we have
|
||||
# but warn the user.
|
||||
log "WARNING: No archive snapshot found. Archiving current artifacts (may be from new feature)."
|
||||
[ -f "$LOOP_DIR/prd.json" ] && cp "$LOOP_DIR/prd.json" "$archive_dir/"
|
||||
[ -f "$LOOP_DIR/progress.md" ] && cp "$LOOP_DIR/progress.md" "$archive_dir/"
|
||||
[ -d "$LOOP_DIR/contracts" ] && cp -r "$LOOP_DIR/contracts" "$archive_dir/"
|
||||
fi
|
||||
|
||||
# Clean up old run's artifacts (progress.md, contracts — NOT prd.json which belongs to new feature)
|
||||
rm -f "$LOOP_DIR/progress.md"
|
||||
rm -rf "$LOOP_DIR/contracts"
|
||||
|
||||
log "Archived previous run to $archive_dir"
|
||||
}
|
||||
Reference in New Issue
Block a user