-
Notifications
You must be signed in to change notification settings - Fork 56
feat: supervisor review triage, compaction resilience, and quality subagents #446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
fb8fc20
3159533
8dee621
be0a65e
ac85cb2
40dddad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,224 @@ | ||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||
| # session-checkpoint-helper.sh - Persist session state to survive context compaction | ||||||||||||||
| # Part of aidevops framework: https://aidevops.sh | ||||||||||||||
| # | ||||||||||||||
| # Usage: | ||||||||||||||
| # session-checkpoint-helper.sh [command] [options] | ||||||||||||||
| # | ||||||||||||||
| # Commands: | ||||||||||||||
| # save Save current session checkpoint | ||||||||||||||
| # load Load and display current checkpoint | ||||||||||||||
| # clear Remove checkpoint file | ||||||||||||||
| # status Show checkpoint age and summary | ||||||||||||||
| # help Show this help | ||||||||||||||
| # | ||||||||||||||
| # Options: | ||||||||||||||
| # --task <id> Current task ID (e.g., t135.9) | ||||||||||||||
| # --next <ids> Comma-separated next task IDs | ||||||||||||||
| # --worktree <path> Active worktree path | ||||||||||||||
| # --branch <name> Active branch name | ||||||||||||||
| # --batch <name> Batch/PR name | ||||||||||||||
| # --note <text> Free-form context note | ||||||||||||||
| # --elapsed <mins> Minutes elapsed in session | ||||||||||||||
| # --target <mins> Target session duration in minutes | ||||||||||||||
| # | ||||||||||||||
| # The checkpoint file is written to: | ||||||||||||||
| # ~/.aidevops/.agent-workspace/tmp/session-checkpoint.md | ||||||||||||||
| # | ||||||||||||||
| # Design: AI agent writes checkpoint after each task completion and reads it | ||||||||||||||
| # before starting the next task. Survives context compaction because state | ||||||||||||||
| # is on disk, not in context window. | ||||||||||||||
|
|
||||||||||||||
| set -euo pipefail | ||||||||||||||
|
|
||||||||||||||
| readonly CHECKPOINT_DIR="${HOME}/.aidevops/.agent-workspace/tmp" | ||||||||||||||
| readonly CHECKPOINT_FILE="${CHECKPOINT_DIR}/session-checkpoint.md" | ||||||||||||||
|
|
||||||||||||||
| readonly GREEN='\033[0;32m' | ||||||||||||||
| readonly YELLOW='\033[1;33m' | ||||||||||||||
| readonly RED='\033[0;31m' | ||||||||||||||
| readonly BOLD='\033[1m' | ||||||||||||||
| readonly DIM='\033[2m' | ||||||||||||||
| readonly NC='\033[0m' | ||||||||||||||
|
|
||||||||||||||
| print_success() { printf "${GREEN}%s${NC}\n" "$1"; } | ||||||||||||||
| print_warning() { printf "${YELLOW}%s${NC}\n" "$1"; } | ||||||||||||||
| print_error() { printf "${RED}%s${NC}\n" "$1" >&2; } | ||||||||||||||
| print_info() { printf "${DIM}%s${NC}\n" "$1"; } | ||||||||||||||
|
|
||||||||||||||
| ensure_dir() { | ||||||||||||||
| if [[ ! -d "$CHECKPOINT_DIR" ]]; then | ||||||||||||||
| mkdir -p "$CHECKPOINT_DIR" | ||||||||||||||
| fi | ||||||||||||||
| return 0 | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| cmd_save() { | ||||||||||||||
| local current_task="" | ||||||||||||||
| local next_tasks="" | ||||||||||||||
| local worktree_path="" | ||||||||||||||
| local branch_name="" | ||||||||||||||
| local batch_name="" | ||||||||||||||
| local note="" | ||||||||||||||
| local elapsed_mins="" | ||||||||||||||
| local target_mins="" | ||||||||||||||
|
|
||||||||||||||
| while [[ $# -gt 0 ]]; do | ||||||||||||||
| case "$1" in | ||||||||||||||
| --task) current_task="$2"; shift 2 ;; | ||||||||||||||
| --next) next_tasks="$2"; shift 2 ;; | ||||||||||||||
| --worktree) worktree_path="$2"; shift 2 ;; | ||||||||||||||
| --branch) branch_name="$2"; shift 2 ;; | ||||||||||||||
| --batch) batch_name="$2"; shift 2 ;; | ||||||||||||||
| --note) note="$2"; shift 2 ;; | ||||||||||||||
| --elapsed) elapsed_mins="$2"; shift 2 ;; | ||||||||||||||
| --target) target_mins="$2"; shift 2 ;; | ||||||||||||||
| *) print_error "Unknown option: $1"; return 1 ;; | ||||||||||||||
| esac | ||||||||||||||
|
coderabbitai[bot] marked this conversation as resolved.
|
||||||||||||||
| done | ||||||||||||||
|
|
||||||||||||||
| ensure_dir | ||||||||||||||
|
|
||||||||||||||
| local timestamp | ||||||||||||||
| timestamp="$(date -u +%Y-%m-%dT%H:%M:%SZ)" | ||||||||||||||
|
|
||||||||||||||
| # Auto-detect git state if not provided | ||||||||||||||
| if [[ -z "$branch_name" ]]; then | ||||||||||||||
| branch_name="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")" | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| # Build checkpoint file | ||||||||||||||
| cat > "$CHECKPOINT_FILE" <<EOF | ||||||||||||||
| # Session Checkpoint | ||||||||||||||
|
|
||||||||||||||
| Updated: ${timestamp} | ||||||||||||||
|
|
||||||||||||||
| ## Current State | ||||||||||||||
|
|
||||||||||||||
| | Field | Value | | ||||||||||||||
| |-------|-------| | ||||||||||||||
| | Current Task | ${current_task:-none} | | ||||||||||||||
| | Branch | ${branch_name} | | ||||||||||||||
| | Worktree | ${worktree_path:-not set} | | ||||||||||||||
| | Batch/PR | ${batch_name:-not set} | | ||||||||||||||
| | Elapsed | ${elapsed_mins:-unknown} min | | ||||||||||||||
| | Target | ${target_mins:-unknown} min | | ||||||||||||||
|
|
||||||||||||||
| ## Next Tasks | ||||||||||||||
|
|
||||||||||||||
| ${next_tasks:-No next tasks specified} | ||||||||||||||
|
|
||||||||||||||
| ## Context Note | ||||||||||||||
|
|
||||||||||||||
| ${note:-No additional context} | ||||||||||||||
|
|
||||||||||||||
| ## Git Status | ||||||||||||||
|
|
||||||||||||||
| $(git status --short 2>/dev/null || echo "Not in a git repo") | ||||||||||||||
|
|
||||||||||||||
| ## Recent Commits (this branch) | ||||||||||||||
|
|
||||||||||||||
| $(git log --oneline -5 2>/dev/null || echo "No commits") | ||||||||||||||
|
|
||||||||||||||
| ## Open Worktrees | ||||||||||||||
|
|
||||||||||||||
| $(git worktree list 2>/dev/null || echo "No worktrees") | ||||||||||||||
| EOF | ||||||||||||||
|
|
||||||||||||||
| print_success "Checkpoint saved: ${CHECKPOINT_FILE}" | ||||||||||||||
| print_info "Task: ${current_task:-none} | Branch: ${branch_name} | ${timestamp}" | ||||||||||||||
| return 0 | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| cmd_load() { | ||||||||||||||
| if [[ ! -f "$CHECKPOINT_FILE" ]]; then | ||||||||||||||
| print_warning "No checkpoint found at ${CHECKPOINT_FILE}" | ||||||||||||||
| print_info "Run: session-checkpoint-helper.sh save --task <id> --next <ids>" | ||||||||||||||
| return 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| cat "$CHECKPOINT_FILE" | ||||||||||||||
| return 0 | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| cmd_clear() { | ||||||||||||||
| if [[ -f "$CHECKPOINT_FILE" ]]; then | ||||||||||||||
| rm "$CHECKPOINT_FILE" | ||||||||||||||
| print_success "Checkpoint cleared" | ||||||||||||||
| else | ||||||||||||||
| print_info "No checkpoint to clear" | ||||||||||||||
| fi | ||||||||||||||
| return 0 | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| cmd_status() { | ||||||||||||||
| if [[ ! -f "$CHECKPOINT_FILE" ]]; then | ||||||||||||||
| print_warning "No active checkpoint" | ||||||||||||||
| return 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| local file_age_seconds | ||||||||||||||
| local now | ||||||||||||||
| local file_mtime | ||||||||||||||
|
|
||||||||||||||
| now="$(date +%s)" | ||||||||||||||
| if [[ "$(uname)" == "Darwin" ]]; then | ||||||||||||||
| file_mtime="$(stat -f %m "$CHECKPOINT_FILE")" | ||||||||||||||
| else | ||||||||||||||
| file_mtime="$(stat -c %Y "$CHECKPOINT_FILE")" | ||||||||||||||
| fi | ||||||||||||||
| file_age_seconds=$(( now - file_mtime )) | ||||||||||||||
|
|
||||||||||||||
| local age_display | ||||||||||||||
| if [[ $file_age_seconds -lt 60 ]]; then | ||||||||||||||
| age_display="${file_age_seconds}s ago" | ||||||||||||||
| elif [[ $file_age_seconds -lt 3600 ]]; then | ||||||||||||||
| age_display="$(( file_age_seconds / 60 ))m ago" | ||||||||||||||
| else | ||||||||||||||
| age_display="$(( file_age_seconds / 3600 ))h $(( (file_age_seconds % 3600) / 60 ))m ago" | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| # Extract key fields | ||||||||||||||
| local current_task | ||||||||||||||
| current_task="$(grep -m1 'Current Task' "$CHECKPOINT_FILE" | sed 's/.*| //' | sed 's/ *$//' || echo "unknown")" | ||||||||||||||
| local branch | ||||||||||||||
| branch="$(grep -m1 'Branch' "$CHECKPOINT_FILE" | sed 's/.*| //' | sed 's/ *$//' || echo "unknown")" | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||||||
|
|
||||||||||||||
| printf '%b\n' "${BOLD}Checkpoint Status${NC}" | ||||||||||||||
| printf " Age: %s\n" "$age_display" | ||||||||||||||
| printf " Task: %s\n" "$current_task" | ||||||||||||||
| printf " Branch: %s\n" "$branch" | ||||||||||||||
| printf " File: %s\n" "$CHECKPOINT_FILE" | ||||||||||||||
|
|
||||||||||||||
| if [[ $file_age_seconds -gt 1800 ]]; then | ||||||||||||||
| print_warning " Warning: Checkpoint is stale (>30min). Consider updating." | ||||||||||||||
| fi | ||||||||||||||
| return 0 | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| cmd_help() { | ||||||||||||||
| # Extract header comment block as help text | ||||||||||||||
| sed -n '2,/^$/p' "$0" | sed 's/^# \?//' | ||||||||||||||
| return 0 | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| # Main dispatch | ||||||||||||||
| main() { | ||||||||||||||
| local command="${1:-help}" | ||||||||||||||
| shift 2>/dev/null || true | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. False positive. This is |
||||||||||||||
|
|
||||||||||||||
| case "$command" in | ||||||||||||||
| save) cmd_save "$@" ;; | ||||||||||||||
| load) cmd_load ;; | ||||||||||||||
| clear) cmd_clear ;; | ||||||||||||||
| status) cmd_status ;; | ||||||||||||||
| help|-h|--help) cmd_help ;; | ||||||||||||||
| *) | ||||||||||||||
| print_error "Unknown command: ${command}" | ||||||||||||||
| cmd_help | ||||||||||||||
| return 1 | ||||||||||||||
| ;; | ||||||||||||||
| esac | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| main "$@" | ||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.