#!/usr/bin/env bash # archeflow-report.sh — Generate a Markdown process report from ArcheFlow JSONL events. # # Usage: ./lib/archeflow-report.sh [--output ] # # Reads a JSONL event file and produces a structured Markdown report showing # the full orchestration process: phases, decisions, reviews, fixes, metrics. # # Requires: jq set -euo pipefail if [[ $# -lt 1 ]]; then echo "Usage: $0 [--output ]" >&2 exit 1 fi EVENT_FILE="$1" OUTPUT="" if [[ "${2:-}" == "--output" && -n "${3:-}" ]]; then OUTPUT="$3" fi if ! command -v jq &> /dev/null; then echo "Error: jq is required but not installed." >&2 exit 1 fi if [[ ! -f "$EVENT_FILE" ]]; then echo "Error: Event file not found: $EVENT_FILE" >&2 exit 1 fi # Helper: extract events by type events_of_type() { jq -c "select(.type == \"$1\")" "$EVENT_FILE" } # Extract run metadata RUN_START=$(events_of_type "run.start" | head -1) RUN_COMPLETE=$(events_of_type "run.complete" | head -1) RUN_ID=$(echo "$RUN_START" | jq -r '.run_id // "unknown"') TASK=$(echo "$RUN_START" | jq -r '.data.task // "unknown"') WORKFLOW=$(echo "$RUN_START" | jq -r '.data.workflow // "unknown"') TEAM=$(echo "$RUN_START" | jq -r '.data.team // "unknown"') # Generate report generate_report() { cat <
Auto-generated from ArcheFlow event log. > Run: \`${RUN_ID}\` | Workflow: \`${WORKFLOW}\` | Team: \`${TEAM}\` --- ## Overview HEADER # Overview table from run.complete if [[ -n "$RUN_COMPLETE" ]]; then STATUS=$(echo "$RUN_COMPLETE" | jq -r '.data.status // "unknown"') CYCLES=$(echo "$RUN_COMPLETE" | jq -r '.data.cycles // "?"') AGENTS=$(echo "$RUN_COMPLETE" | jq -r '.data.agents_total // "?"') FIXES=$(echo "$RUN_COMPLETE" | jq -r '.data.fixes_total // "?"') SHADOWS=$(echo "$RUN_COMPLETE" | jq -r '.data.shadows // "0"') DURATION_MS=$(echo "$RUN_COMPLETE" | jq -r '.data.duration_ms // "0"') DURATION_MIN=$(( DURATION_MS / 60000 )) cat </dev/null || true echo "" ;; fix.applied) SOURCE=$(echo "$event" | jq -r '.data.source // "unknown"') FINDING=$(echo "$event" | jq -r '.data.finding // "unknown"') FILE=$(echo "$event" | jq -r '.data.file // ""') LINE=$(echo "$event" | jq -r '.data.line // ""') if [[ -n "$FILE" && "$LINE" != "null" && -n "$LINE" ]]; then echo "- **Fix** (${SOURCE}): ${FINDING} — \`${FILE}:${LINE}\`" else echo "- **Fix** (${SOURCE}): ${FINDING}" fi ;; shadow.detected) ARCHETYPE=$(echo "$event" | jq -r '.data.archetype // "unknown"') SHADOW=$(echo "$event" | jq -r '.data.shadow // "unknown"') ACTION=$(echo "$event" | jq -r '.data.action // "unknown"') echo "- **Shadow** ⚠️ ${ARCHETYPE}: ${SHADOW} → ${ACTION}" echo "" ;; cycle.boundary) CYCLE=$(echo "$event" | jq -r '.data.cycle // "?"') MAX=$(echo "$event" | jq -r '.data.max_cycles // "?"') MET=$(echo "$event" | jq -r '.data.met // false') NEXT=$(echo "$event" | jq -r '.data.next_action // "unknown"') echo "" echo "---" echo "" echo "**Cycle ${CYCLE}/${MAX}** — exit condition met: ${MET} → ${NEXT}" echo "" ;; esac done < "$EVENT_FILE" # Artifacts list from run.complete if [[ -n "$RUN_COMPLETE" ]]; then echo "" echo "---" echo "" echo "## Artifacts" echo "" echo "$RUN_COMPLETE" | jq -r '(.data.artifacts // [])[] | "- `" + . + "`"' fi } if [[ -n "$OUTPUT" ]]; then generate_report > "$OUTPUT" echo "Report written to: $OUTPUT" >&2 else generate_report fi