Added standardized workflows for automated publishing on push to main/master. Configuration-driven, version-checked, workspace-aware workflows. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
114 lines
3.6 KiB
Bash
Executable file
114 lines
3.6 KiB
Bash
Executable file
#!/bin/bash
|
|
# Smart suggestion for next action
|
|
# Usage: ./workflow/continue
|
|
|
|
WORKTREE_BASE="worktrees"
|
|
|
|
# Refresh symlinks first
|
|
"$(dirname "$0")/refresh" > /dev/null
|
|
|
|
echo "=== WORKFLOW CONTINUE ==="
|
|
echo ""
|
|
|
|
# Check for blocked worktrees first
|
|
BLOCKED_LIST=()
|
|
UNBLOCKED_LIST=()
|
|
|
|
for dated_dir in "$WORKTREE_BASE"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]; do
|
|
[[ -d "$dated_dir" ]] || continue
|
|
for worktree in "$dated_dir"/*/; do
|
|
[[ -d "$worktree" ]] || continue
|
|
NAME=$(basename "$worktree")
|
|
|
|
if [[ -f "$worktree/STATUS.md" ]]; then
|
|
BLOCKED=$(grep "^blocked:" "$worktree/STATUS.md" 2>/dev/null | cut -d: -f2 | tr -d ' ')
|
|
if [[ "$BLOCKED" == "true" ]]; then
|
|
REASON=$(grep "^blocker_reason:" "$worktree/STATUS.md" 2>/dev/null | cut -d: -f2-)
|
|
BLOCKED_LIST+=("$NAME|$REASON|$worktree")
|
|
else
|
|
# Get last modified time
|
|
MTIME=$(stat -c %Y "$worktree/STATUS.md" 2>/dev/null || stat -f %m "$worktree/STATUS.md" 2>/dev/null || echo 0)
|
|
PHASE=$(grep "^phase:" "$worktree/STATUS.md" 2>/dev/null | cut -d: -f2 | tr -d ' ')
|
|
UNBLOCKED_LIST+=("$MTIME|$NAME|$PHASE|$worktree")
|
|
fi
|
|
fi
|
|
done
|
|
done
|
|
|
|
# Sort unblocked by most recent first
|
|
IFS=$'\n' SORTED_UNBLOCKED=($(sort -t'|' -k1 -nr <<< "${UNBLOCKED_LIST[*]}"))
|
|
unset IFS
|
|
|
|
# Check blockers that might be resolvable
|
|
if [[ ${#BLOCKED_LIST[@]} -gt 0 ]]; then
|
|
echo "BLOCKED WORK (check if any can be unblocked):"
|
|
echo ""
|
|
for item in "${BLOCKED_LIST[@]}"; do
|
|
NAME=$(echo "$item" | cut -d'|' -f1)
|
|
REASON=$(echo "$item" | cut -d'|' -f2)
|
|
echo " ❌ $NAME"
|
|
echo " Reason:$REASON"
|
|
echo " Unblock: ./workflow/unblock $NAME"
|
|
echo ""
|
|
done
|
|
fi
|
|
|
|
# Show recommendation
|
|
if [[ ${#SORTED_UNBLOCKED[@]} -gt 0 ]]; then
|
|
# Get most recent unblocked
|
|
BEST=$(echo "${SORTED_UNBLOCKED[0]}")
|
|
BEST_NAME=$(echo "$BEST" | cut -d'|' -f2)
|
|
BEST_PHASE=$(echo "$BEST" | cut -d'|' -f3)
|
|
BEST_PATH=$(echo "$BEST" | cut -d'|' -f4)
|
|
|
|
echo "RECOMMENDED: Continue with '$BEST_NAME' (phase: $BEST_PHASE)"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " cd $BEST_PATH"
|
|
echo " cat HANDOFF.md"
|
|
echo ""
|
|
|
|
# Show HANDOFF.md preview if it exists
|
|
if [[ -f "${BEST_PATH}HANDOFF.md" ]]; then
|
|
echo "--- HANDOFF.md Preview ---"
|
|
# Show Goal and Next Steps sections
|
|
awk '/^## Goal/,/^## [^G]/' "${BEST_PATH}HANDOFF.md" | head -10
|
|
echo "..."
|
|
awk '/^## Next Steps/,/^## |^$/' "${BEST_PATH}HANDOFF.md" | head -10
|
|
echo "---"
|
|
fi
|
|
|
|
# Show other options if any
|
|
if [[ ${#SORTED_UNBLOCKED[@]} -gt 1 ]]; then
|
|
echo ""
|
|
echo "Other active work:"
|
|
for i in "${!SORTED_UNBLOCKED[@]}"; do
|
|
[[ $i -eq 0 ]] && continue
|
|
ITEM="${SORTED_UNBLOCKED[$i]}"
|
|
NAME=$(echo "$ITEM" | cut -d'|' -f2)
|
|
PHASE=$(echo "$ITEM" | cut -d'|' -f3)
|
|
echo " - $NAME (phase: $PHASE)"
|
|
done
|
|
fi
|
|
else
|
|
# No active work
|
|
echo "NO ACTIVE WORK"
|
|
echo ""
|
|
|
|
# Check project/STATUS.md for suggestions
|
|
if [[ -f "project/STATUS.md" ]]; then
|
|
echo "Project status:"
|
|
PHASE=$(grep -m1 "^\*\*Phase\*\*:" "project/STATUS.md" 2>/dev/null | sed 's/\*\*Phase\*\*: //')
|
|
if [[ -n "$PHASE" ]]; then
|
|
echo " Phase: $PHASE"
|
|
fi
|
|
echo ""
|
|
fi
|
|
|
|
echo "Start new work:"
|
|
echo " ./workflow/start <name> '<purpose>'"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " ./workflow/start fix-auth-bug 'Fix OAuth token refresh'"
|
|
echo " ./workflow/start feature-dashboard 'Add analytics dashboard'"
|
|
fi
|