174 lines
5.0 KiB
Bash
174 lines
5.0 KiB
Bash
#!/usr/bin/env bash
|
|||
|
|
# pi-automaton.sh — Pi Dev automaton context printer.
|
||
|
|
#
|
||
|
|
# Prints automaton project/framework context for the user to paste as their
|
||
|
|
# first message to a Pi Dev agent. Does NOT launch pi.
|
||
|
|
#
|
||
|
|
# Usage:
|
||
|
|
# cd /path/to/project
|
||
|
|
# bash ~/.automaton/scripts/pi-automaton.sh
|
||
|
|
#
|
||
|
|
# Copy the output and paste it as your first message in Pi Dev.
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
FRAMEWORK_DIR="$HOME/.automaton"
|
||
|
|
STATUS_PY="$FRAMEWORK_DIR/scripts/status.py"
|
||
|
|
|
||
|
|
# Colors
|
||
|
|
BOLD='\033[1m'
|
||
|
|
DIM='\033[2m'
|
||
|
|
NC='\033[0m'
|
||
|
|
|
||
|
|
info() { echo -e " $1"; }
|
||
|
|
dim() { echo -e " ${DIM}$1${NC}"; }
|
||
|
|
dim_nl(){ echo -e "${DIM}$1${NC}"; }
|
||
|
|
|
||
|
|
# --- Scope detection ---
|
||
|
|
CWD="$(pwd)"
|
||
|
|
if [ "$CWD" = "$FRAMEWORK_DIR" ] || [ "${CWD##"$FRAMEWORK_DIR"}" != "$CWD" ]; then
|
||
|
|
SCOPE="framework"
|
||
|
|
SCOPE_LABEL="framework mode (automaton itself)"
|
||
|
|
PROJECT_DIR="$FRAMEWORK_DIR"
|
||
|
|
elif [ -d "$CWD/.automaton" ]; then
|
||
|
|
SCOPE="project"
|
||
|
|
SCOPE_LABEL="project mode ($(basename "$CWD"))"
|
||
|
|
PROJECT_DIR="$CWD"
|
||
|
|
else
|
||
|
|
echo ""
|
||
|
|
echo "No automaton project detected in $CWD"
|
||
|
|
echo ""
|
||
|
|
echo "To onboard this project:"
|
||
|
|
echo " bash $FRAMEWORK_DIR/scripts/onboard-project.sh ."
|
||
|
|
echo ""
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
TASKS_DIR="$PROJECT_DIR/.automaton/tasks"
|
||
|
|
MODELS_FILE="$PROJECT_DIR/.automaton/models.json"
|
||
|
|
CONFIG_FILE="$PROJECT_DIR/.automaton/config.md"
|
||
|
|
AGENTS_FILE="$PROJECT_DIR/.automaton/AGENTS.md"
|
||
|
|
|
||
|
|
# --- Collect data ---
|
||
|
|
|
||
|
|
# Active tasks via status.py --audit --json
|
||
|
|
TASKS_JSON=""
|
||
|
|
if [ -f "$STATUS_PY" ] && [ -d "$TASKS_DIR" ]; then
|
||
|
|
TASKS_JSON=$(python3 "$STATUS_PY" --audit --json --project "$PROJECT_DIR" 2>/dev/null || true)
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Default model
|
||
|
|
DEFAULT_MODEL=""
|
||
|
|
if [ -f "$MODELS_FILE" ]; then
|
||
|
|
DEFAULT_MODEL=$(python3 -c "
|
||
|
|
import json
|
||
|
|
with open('$MODELS_FILE') as f:
|
||
|
|
m = json.load(f)
|
||
|
|
print(m.get('default', ''))
|
||
|
|
" 2>/dev/null || echo "")
|
||
|
|
fi
|
||
|
|
|
||
|
|
# VRAM context snippet from config.md
|
||
|
|
CONFIG_SNIPPET=""
|
||
|
|
if [ -f "$CONFIG_FILE" ]; then
|
||
|
|
CONFIG_SNIPPET=$(grep -i 'context\|headroom\|target' "$CONFIG_FILE" 2>/dev/null | head -3 | sed 's/^/ /')
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Project rules from AGENTS.md
|
||
|
|
RULES_TEXT=""
|
||
|
|
if [ -f "$AGENTS_FILE" ]; then
|
||
|
|
RULES_TEXT=$(grep -v -E '^#|^$' "$AGENTS_FILE" 2>/dev/null | head -10)
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Can-edit status
|
||
|
|
CAN_EDIT_OUTPUT=""
|
||
|
|
if [ -f "$STATUS_PY" ]; then
|
||
|
|
CAN_EDIT_OUTPUT=$(python3 "$STATUS_PY" --can-edit --json --project "$PROJECT_DIR" 2>/dev/null || true)
|
||
|
|
fi
|
||
|
|
|
||
|
|
# --- Build task list ---
|
||
|
|
TASK_LINES=""
|
||
|
|
TASK_COUNT=0
|
||
|
|
if [ -n "$TASKS_JSON" ]; then
|
||
|
|
while IFS=$'\t' read -r name state edit_phase; do
|
||
|
|
if [ -n "$name" ]; then
|
||
|
|
FLAG=""
|
||
|
|
if [ "$edit_phase" = "true" ]; then
|
||
|
|
FLAG=" (edit allowed)"
|
||
|
|
elif [ "$state" != "backlog" ] && [ "$state" != "done" ] && [ "$state" != "blocked" ]; then
|
||
|
|
FLAG=" (read-only)"
|
||
|
|
fi
|
||
|
|
TASK_LINES+=" * $name\t\t$state$FLAG\n"
|
||
|
|
TASK_COUNT=$((TASK_COUNT + 1))
|
||
|
|
fi
|
||
|
|
done < <(echo "$TASKS_JSON" | python3 -c "
|
||
|
|
import json, sys
|
||
|
|
data = json.load(sys.stdin)
|
||
|
|
tasks = []
|
||
|
|
for t in data.get('tasks', []):
|
||
|
|
tasks.append((t['name'], t['state']))
|
||
|
|
# Map edit-eligible phases
|
||
|
|
EDIT_PHASES = {'implement', 'doc_review'}
|
||
|
|
for name, state in tasks:
|
||
|
|
ep = 'true' if state in EDIT_PHASES else 'false'
|
||
|
|
print(f'{name}\t{state}\t{ep}')
|
||
|
|
" 2>/dev/null || true)
|
||
|
|
fi
|
||
|
|
|
||
|
|
# --- Render ---
|
||
|
|
LINE="══════════════════════════════════════════════════"
|
||
|
|
SEP="──────────────────────────────────────────────────"
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
echo -e "${BOLD}${LINE}${NC}"
|
||
|
|
echo -e "${BOLD} Automaton Context — $SCOPE_LABEL${NC}"
|
||
|
|
echo -e "${BOLD}${LINE}${NC}"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
echo -e "${BOLD}This project uses the automaton workflow framework.${NC}"
|
||
|
|
info "Tasks are tracked in $(basename "$PROJECT_DIR")/.automaton/tasks/"
|
||
|
|
info "and flow through phases:"
|
||
|
|
info "backlog → research → implement → code_review → bug_find → ... → complete"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
if [ -n "$TASK_LINES" ]; then
|
||
|
|
echo -e "${BOLD}Active tasks:${NC}"
|
||
|
|
echo -e "$TASK_LINES"
|
||
|
|
echo ""
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [ -n "$DEFAULT_MODEL" ]; then
|
||
|
|
echo -e "${BOLD}Default model:${NC} $DEFAULT_MODEL"
|
||
|
|
echo ""
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [ -n "$CONFIG_SNIPPET" ]; then
|
||
|
|
echo -e "${BOLD}Configuration:${NC}"
|
||
|
|
echo "$CONFIG_SNIPPET"
|
||
|
|
echo ""
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo -e "${BOLD}To work on a task:${NC}"
|
||
|
|
info "python3 ~/.automaton/scripts/status.py --transition <phase> --task <name>"
|
||
|
|
echo ""
|
||
|
|
echo -e "${BOLD}To create a new task:${NC}"
|
||
|
|
info "python3 ~/.automaton/scripts/status.py --create-task <name>"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
if [ -n "$RULES_TEXT" ]; then
|
||
|
|
echo -e "${BOLD}Project rules (from AGENTS.md):${NC}"
|
||
|
|
echo "$RULES_TEXT" | head -5
|
||
|
|
echo ""
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo -e "${BOLD}Important:${NC}"
|
||
|
|
info "Only modify files when a task is in ${BOLD}implement${NC} or ${BOLD}doc_review${NC} phase"
|
||
|
|
info "All phase transitions go through status.py"
|
||
|
|
info "The automaton-guard-pi plugin blocks edits outside allowed phases"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
echo -e "${DIM}$SEP${NC}"
|
||
|
|
dim_nl "Copy this entire block and paste it as your first message"
|
||
|
|
dim_nl "to the Pi Dev agent to provide automaton context."
|
||
|
|
echo -e "${DIM}$SEP${NC}"
|
||
|
|
echo ""
|