Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .agent/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,15 @@
- Parallel sessions inheriting wrong branch state
- "Your local changes would be overwritten" errors

**When option 3 is acceptable**: Documentation-only changes (README, CHANGELOG, docs/), typo fixes, version bumps via release script.
**When option 3 is acceptable**: Documentation-only changes (README, CHANGELOG, docs/), typo fixes, version bumps via release script, **planning files (TODO.md, todo/)**.
**When option 3 is NOT acceptable**: Any code changes, configuration files, scripts.

**Planning files exception**: TODO.md and todo/ can be edited directly on main and auto-committed:
```bash

Check notice on line 70 in .agent/AGENTS.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

.agent/AGENTS.md#L70

Fenced code blocks should be surrounded by blank lines
~/.aidevops/agents/scripts/planning-commit-helper.sh "plan: add new task"
```

Check notice on line 72 in .agent/AGENTS.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

.agent/AGENTS.md#L72

Fenced code blocks should be surrounded by blank lines
Planning files are metadata about work, not the work itself - they don't need PR review.

4. Create worktree: `~/.aidevops/agents/scripts/worktree-helper.sh add {type}/{name}`
5. After creating branch, call `session-rename_sync_branch` tool

Expand Down
25 changes: 25 additions & 0 deletions .agent/plan-plus.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,31 @@ Plan+ can write directly to planning files:

**Use this for:** Capturing tasks, writing plans, documenting decisions.

## Auto-Commit Planning Files

After modifying TODO.md or todo/, commit and push immediately:

```bash
~/.aidevops/agents/scripts/planning-commit-helper.sh "plan: {description}"
```

**When to auto-commit:**
- After adding a new task
- After updating task status
- After writing or updating a plan

**Commit message conventions:**

| Action | Message |
|--------|---------|
| New task | `plan: add {task title}` |
| Status update | `plan: {task} → done` |
| New plan | `plan: add {plan name}` |
| Batch updates | `plan: batch planning updates` |

**Why this bypasses branch/PR workflow:** Planning files are metadata about work,
not the work itself. They don't need code review - just quick persistence.

## Handoff to Build+ (IMPORTANT)

**When all planning decisions are made and you're ready to implement code:**
Expand Down
209 changes: 209 additions & 0 deletions .agent/scripts/planning-commit-helper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
#!/bin/bash
# shellcheck disable=SC2310
# =============================================================================
# Planning File Auto-Commit Helper
# =============================================================================
# Commits and pushes changes to TODO.md and todo/ without branch ceremony.
# Called automatically by Plan+ agent after planning file modifications.
#
# Usage:
# planning-commit-helper.sh "plan: add new task"
# planning-commit-helper.sh --check # Just check if changes exist
# planning-commit-helper.sh --status # Show planning file status
#
# Exit codes:
# 0 - Success (or no changes to commit)
# 1 - Error (not in git repo, etc.)
# =============================================================================

set -euo pipefail

# Colors
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly NC='\033[0m'

# Planning file patterns
readonly PLANNING_PATTERNS="^TODO\.md$|^todo/"

log_info() {
echo -e "${BLUE}[plan]${NC} $1"
}

log_success() {
echo -e "${GREEN}[plan]${NC} $1"
}

log_warning() {
echo -e "${YELLOW}[plan]${NC} $1"
}

log_error() {
echo -e "${RED}[plan]${NC} $1" >&2
}

# Check if we're in a git repository
check_git_repo() {
if ! git rev-parse --is-inside-work-tree &>/dev/null; then
log_error "Not in a git repository"
return 1
fi
return 0
}

# Check if there are planning file changes
has_planning_changes() {
# Check both staged and unstaged changes
if git diff --name-only HEAD 2>/dev/null | grep -qE "$PLANNING_PATTERNS"; then
return 0
fi
if git diff --name-only --cached 2>/dev/null | grep -qE "$PLANNING_PATTERNS"; then
return 0
fi
# Also check untracked files in todo/
if git ls-files --others --exclude-standard 2>/dev/null | grep -qE "$PLANNING_PATTERNS"; then
return 0
fi
return 1
}
Comment on lines +56 to +70
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Edge case: git diff HEAD fails on repos with no commits.

On a brand new repository with no commits, git diff --name-only HEAD returns an error (fatal: ambiguous argument 'HEAD'). With pipefail enabled, this could cause unexpected behavior.

🔧 Suggested fix for initial-commit edge case
 has_planning_changes() {
-    # Check both staged and unstaged changes
-    if git diff --name-only HEAD 2>/dev/null | grep -qE "$PLANNING_PATTERNS"; then
+    # Check unstaged changes (works even with no commits)
+    if git diff --name-only 2>/dev/null | grep -qE "$PLANNING_PATTERNS"; then
         return 0
     fi
     if git diff --name-only --cached 2>/dev/null | grep -qE "$PLANNING_PATTERNS"; then

Using git diff --name-only (without HEAD) checks working tree vs index, which works on fresh repos.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Check if there are planning file changes
has_planning_changes() {
# Check both staged and unstaged changes
if git diff --name-only HEAD 2>/dev/null | grep -qE "$PLANNING_PATTERNS"; then
return 0
fi
if git diff --name-only --cached 2>/dev/null | grep -qE "$PLANNING_PATTERNS"; then
return 0
fi
# Also check untracked files in todo/
if git ls-files --others --exclude-standard 2>/dev/null | grep -qE "$PLANNING_PATTERNS"; then
return 0
fi
return 1
}
# Check if there are planning file changes
has_planning_changes() {
# Check unstaged changes (works even with no commits)
if git diff --name-only 2>/dev/null | grep -qE "$PLANNING_PATTERNS"; then
return 0
fi
if git diff --name-only --cached 2>/dev/null | grep -qE "$PLANNING_PATTERNS"; then
return 0
fi
# Also check untracked files in todo/
if git ls-files --others --exclude-standard 2>/dev/null | grep -qE "$PLANNING_PATTERNS"; then
return 0
fi
return 1
}
🤖 Prompt for AI Agents
In @.agent/scripts/planning-commit-helper.sh around lines 56 - 70, In
has_planning_changes(), avoid using the failing invocation "git diff --name-only
HEAD" on repos with no commits; replace that first check with "git diff
--name-only" (working tree vs index) or guard the HEAD call with a pre-check
like "git rev-parse --verify HEAD >/dev/null 2>&1 && git diff --name-only HEAD
..." so the function won't error on initial commits; update the code that
currently calls "git diff --name-only HEAD" to the safer invocation and leave
the cached and ls-files checks unchanged.


# List planning file changes
list_planning_changes() {
local changes=""

# Staged changes
local staged
staged=$(git diff --name-only --cached 2>/dev/null | grep -E "$PLANNING_PATTERNS" || true)

# Unstaged changes
local unstaged
unstaged=$(git diff --name-only 2>/dev/null | grep -E "$PLANNING_PATTERNS" || true)

# Untracked
local untracked
untracked=$(git ls-files --others --exclude-standard 2>/dev/null | grep -E "$PLANNING_PATTERNS" || true)

# Combine unique
changes=$(echo -e "${staged}\n${unstaged}\n${untracked}" | sort -u | grep -v '^$' || true)
echo "$changes"
}

# Show status of planning files
show_status() {
check_git_repo || return 1

echo "Planning file status:"
echo "====================="

if has_planning_changes; then
echo -e "${YELLOW}Modified planning files:${NC}"
list_planning_changes | while read -r file; do
[[ -n "$file" ]] && echo " - $file"
done
else
echo -e "${GREEN}No planning file changes${NC}"
fi

return 0
}

# Main commit function
commit_planning_files() {
local commit_msg="${1:-plan: update planning files}"

check_git_repo || return 1

# Check for changes
if ! has_planning_changes; then
log_info "No planning file changes to commit"
return 0
fi

# Show what we're committing
log_info "Planning files to commit:"
list_planning_changes | while read -r file; do
[[ -n "$file" ]] && echo " - $file"
done

# Pull latest to avoid conflicts (rebase to keep history clean)
local current_branch
current_branch=$(git branch --show-current)
if git remote get-url origin &>/dev/null; then
log_info "Pulling latest changes..."
if ! git pull --rebase origin "$current_branch" 2>/dev/null; then
log_warning "Pull failed (may be offline or new branch)"
fi
fi

# Stage only planning files
git add TODO.md 2>/dev/null || true
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git add TODO.md / git add todo/ typically won’t stage deletions (e.g., removing a file under todo/), so planning-file removals may be left uncommitted even though this helper detected changes.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎

git add todo/ 2>/dev/null || true
Comment on lines +141 to +142
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The current implementation uses git add TODO.md and git add todo/ to stage files. This is a bit too broad, as git add todo/ will stage all modified and untracked files within that directory, potentially including files not intended for this commit.

A more robust approach is to use the list_planning_changes function to get a precise list of changed planning files and stage only them. This can be done safely using mapfile to handle filenames with special characters, ensuring only intended files are part of the commit.

Suggested change
git add TODO.md 2>/dev/null || true
git add todo/ 2>/dev/null || true
mapfile -t files_to_add < <(list_planning_changes)
if ((${#files_to_add[@]} > 0)); then
# Using an array with -- ensures filenames are handled safely.
git add -- "${files_to_add[@]}"
fi


# Check if anything was staged
if git diff --cached --quiet 2>/dev/null; then
log_info "No changes staged after adding planning files"
return 0
fi

# Commit (skip hooks - planning commits don't need full linting)
log_info "Committing: $commit_msg"
if ! git commit -m "$commit_msg" --no-verify; then
log_error "Commit failed"
return 1
fi

# Push (silent fail if offline or no permissions)
if git remote get-url origin &>/dev/null; then
log_info "Pushing to remote..."
if git push origin HEAD 2>/dev/null; then
log_success "Planning files committed and pushed"
else
log_warning "Committed locally (push failed - will retry later)"
fi
else
log_success "Committed locally (no remote configured)"
fi

return 0
}

# Main
main() {
case "${1:-}" in
--check)
check_git_repo || exit 1
if has_planning_changes; then
echo "PLANNING_CHANGES=true"
exit 0
else
echo "PLANNING_CHANGES=false"
exit 0
fi
;;
--status)
show_status
exit $?
;;
--help|-h)
echo "Usage: planning-commit-helper.sh [OPTIONS] [COMMIT_MESSAGE]"
echo ""
echo "Options:"
echo " --check Check if planning files have changes"
echo " --status Show planning file status"
echo " --help Show this help"
echo ""
echo "Examples:"
echo " planning-commit-helper.sh 'plan: add new task'"
echo " planning-commit-helper.sh --check"
exit 0
;;
*)
commit_planning_files "$@"
exit $?
;;
esac
}

main "$@"
3 changes: 2 additions & 1 deletion .agent/scripts/pre-edit-check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ is_docs_only() {
local code_patterns="feature|fix|bug|implement|refactor|add.*function|update.*code|create.*script|modify.*config|change.*logic|new.*api|endpoint|enhance|port|ssl|helper"

# Docs-only indicators (positive match)
local docs_patterns="^readme|^changelog|^documentation|docs/|typo|spelling|comment only|license only|^update readme|^update changelog|^update docs"
# Includes planning files (TODO.md, todo/) which can be edited on main
local docs_patterns="^readme|^changelog|^documentation|docs/|typo|spelling|comment only|license only|^update readme|^update changelog|^update docs|^todo|todo\.md|plans\.md|planning|^add task|^update task|backlog"

# Check for code patterns first (takes precedence)
if echo "$task_lower" | grep -qE "$code_patterns"; then
Expand Down
Loading