feat(localhost): add port management and loop-mode auto-branch#52
feat(localhost): add port management and loop-mode auto-branch#52marcusquinn merged 2 commits intomainfrom
Conversation
- Add --loop-mode flag to pre-edit-check.sh for autonomous branch decisions - Docs-only tasks (README, CHANGELOG) stay on main - Code tasks auto-signal worktree creation (exit code 2) - Add port management functions to localhost-helper.sh: - check-port: Check if port is available, suggest alternative - find-port: Find next available port from start - list-ports: List common dev ports in use - kill-port: Kill process using specified port - Document localhost standards in AGENTS.md: - Always check port before starting services - Use .local domains for password manager compatibility - Always use SSL via Traefik proxy - Update localhost.md with rationale: - Why password managers need HTTPS - Standard setup workflow - Port conflict avoidance - Update loop agents (full-loop.md, ralph-loop.md) with auto-branch docs
WalkthroughThis PR adds autonomous loop-mode decisioning for agents (docs-only vs code), automates branch/worktree creation when needed, introduces port-management utilities and CLI commands in localhost-helper.sh, and updates related documentation to reflect .local+SSL standards and the new workflows. Changes
Sequence Diagram(s)sequenceDiagram
participant Agent as Autonomous Agent
participant FullLoop as full-loop.md (loop runner)
participant PreCheck as pre-edit-check.sh
participant Classifier as is_docs_only()
participant BranchMgr as worktree/branch helper
Agent->>FullLoop: Start loop with task description
FullLoop->>PreCheck: Invoke pre-edit-check.sh --loop-mode --task "desc"
PreCheck->>Classifier: classify(task)
Classifier-->>PreCheck: docs-only / code
alt Docs-only
PreCheck-->>FullLoop: exit 0 (LOOP-AUTO proceed)
FullLoop->>Agent: continue on main
else Code
PreCheck-->>FullLoop: exit 2 (LOOP-AUTO create worktree)
FullLoop->>BranchMgr: sanitize name & create worktree/branch
BranchMgr-->>FullLoop: worktree ready
FullLoop->>Agent: continue on feature worktree
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Sun Jan 11 16:38:03 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
There was a problem hiding this comment.
Code Review
This pull request introduces significant improvements for both autonomous agent workflows and local development setup. The addition of --loop-mode in pre-edit-check.sh is a smart enhancement that will prevent autonomous agents from getting stuck. The new port management functions in localhost-helper.sh are a welcome addition for avoiding common local development frustrations. The documentation updates are thorough and clearly explain the new features and standards. My review includes a few suggestions to improve the robustness and performance of the new shell scripts and to clarify an example in the documentation.
.agent/scripts/localhost-helper.sh
Outdated
| sleep 1 | ||
| if is_port_free "$port"; then | ||
| print_success "Port $port is now free" | ||
| return 0 | ||
| else | ||
| print_error "Failed to free port $port" | ||
| return 1 | ||
| fi |
There was a problem hiding this comment.
Using a fixed sleep 1 to wait for a port to be freed creates a race condition. The process might not have released the port within that second, especially on a loaded system, leading the script to incorrectly report a failure. A more reliable approach is to poll for a short period, repeatedly checking if the port has become free.
| sleep 1 | |
| if is_port_free "$port"; then | |
| print_success "Port $port is now free" | |
| return 0 | |
| else | |
| print_error "Failed to free port $port" | |
| return 1 | |
| fi | |
| # Wait up to 3 seconds for the port to become free | |
| for _ in {1..6}; do | |
| if is_port_free "$port"; then | |
| print_success "Port $port is now free" | |
| return 0 | |
| fi | |
| sleep 0.5 | |
| done | |
| print_error "Failed to free port $port" | |
| return 1 |
.agent/scripts/localhost-helper.sh
Outdated
| local dev_ports="3000 3001 3002 3003 4000 5000 5173 5174 8000 8080 8085 8888 9000 9222 11235" | ||
|
|
||
| for port in $dev_ports; do |
There was a problem hiding this comment.
Using a string for dev_ports is prone to word-splitting issues if any future values contain spaces or other special characters. It's more robust and a best practice in shell scripting to use a bash array for lists of items.
| local dev_ports="3000 3001 3002 3003 4000 5000 5173 5174 8000 8080 8085 8888 9000 9222 11235" | |
| for port in $dev_ports; do | |
| local dev_ports=(3000 3001 3002 3003 4000 5000 5173 5174 8000 8080 8085 8888 9000 9222 11235) | |
| for port in "${dev_ports[@]}"; do |
.agent/scripts/pre-edit-check.sh
Outdated
| is_docs_only() { | ||
| local task="$1" | ||
| local task_lower | ||
| task_lower=$(echo "$task" | tr '[:upper:]' '[:lower:]') |
There was a problem hiding this comment.
For better performance and to avoid spawning a subshell, you can use bash's built-in parameter expansion for converting to lowercase. This is more efficient than piping to tr. This requires bash 4.0+, which is a reasonable assumption for a modern development script.
| task_lower=$(echo "$task" | tr '[:upper:]' '[:lower:]') | |
| task_lower="${task,,}" |
.agent/services/hosting/localhost.md
Outdated
| localhost-helper.sh find-port 3000 | ||
|
|
||
| # 3. Create app with .local domain + SSL | ||
| localhost-helper.sh create-app myapp myapp.local 3000 true docker |
There was a problem hiding this comment.
This example workflow could be confusing. Step 2 (find-port) implies a conflict might occur and a new port is found, but Step 3 proceeds with the original port 3000. To make the example clearer and demonstrate the intended workflow, this step should use the port that would have been suggested by find-port in case of a conflict.
| localhost-helper.sh create-app myapp myapp.local 3000 true docker | |
| localhost-helper.sh create-app myapp myapp.local 3001 true docker |
- Use bash array for dev_ports list (more robust) - Poll for port release instead of fixed sleep (avoid race condition) - Use bash 4.0+ parameter expansion for lowercase (more efficient) - Fix documentation examples to use variable for found port
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
.agent/services/hosting/localhost.md (3)
118-155: Resolve MCP port inconsistency.The Quick Reference (line 23) states "MCP on port 8085", but the Configuration Structure example (line 139) shows
"mcp_port": 3001. Clarify the correct default port and whether this is environment-specific or has changed.
305-336: Address critical documentation scope gap: only ~2 of 16 documented commands are implemented.The Development Workflow section (lines 305–336) and subsequent sections document commands that don't exist in
localhost-helper.sh. Actual implemented commands are limited to:
- Port management:
check-port,find-port,list-ports,kill-port- DNS/Proxy setup:
setup-dns,setup-proxy- App management:
create-app,list- LocalWP:
list-localwp,setup-localwp-domain- MCP:
start-mcp,stop-mcpMissing entirely:
start-stack,stop-stack,restart-services,health-checkcreate-project,clone-template,setup-env,start-projecttest-mcp,mcp-querydocker-up,docker-down,docker-logs,docker-execUsers following the documented examples will encounter "Unknown command" errors. Either:
- Implement the documented commands to match documentation
- Remove aspirational sections and document only implemented features
- Clearly mark sections as "🚀 Planned Features" to set expectations
This documentation debt should be resolved before merging.
165-232: Documentation significantly exceeds implementation—most commands do not exist.The Usage Examples section documents 17 commands across four subsections, but only 4 are actually implemented in
localhost-helper.sh:
Section Documented Implemented Status Basic Commands environments, start, stop, status None 0% LocalWP Integration localwp-sites, start-site, stop-site, site-info, start-mcp start-mcp (list-localwp exists) 20% SSL Management generate-ssl, install-ssl, list-ssl, renew-ssl generate-cert only 0% Port Management list-ports, check-port, kill-port, forward-port list-ports, check-port, find-port, kill-port 75% Users will encounter "command not found" errors on fundamental operations like
start wordpress(documented at line 176) andgenerate-ssl mysite.local(documented at line 205). Remove aspirational commands or clearly mark them as "Planned Features" with estimated timelines.
🤖 Fix all issues with AI agents
In @.agent/scripts/localhost-helper.sh:
- Around line 160-187: The kill_port function currently uses kill -9
unconditionally; modify kill_port to prompt for confirmation (unless a new
--force flag or FORCED=true env is passed) before killing, attempt a graceful
kill first (kill PID with SIGTERM), wait/recheck with is_port_free, and only if
still occupied then escalate to SIGKILL and log the escalation via
print_warning/print_error/print_success; ensure the confirmation prompt
references the PIDs and port, and make non-interactive scripts possible by
honoring the --force flag or environment variable so callers can skip
confirmation.
In @.agent/workflows/ralph-loop.md:
- Around line 89-92: The docs table in ralph-loop.md is missing several
detection patterns present in pre-edit-check.sh; update the Task Type table so
the "Detection Keywords" column contains the full regex patterns (or expanded
keyword lists) used by pre-edit-check.sh — specifically add docs-only patterns:
"comment only", "license only", "^update readme", "^update changelog", "^update
docs"; and add code patterns like "add.*function", "update.*code",
"create.*script", "modify.*config", "change.*logic", "new.*api", "endpoint",
"port", "ssl", "helper" (or replace the simple keywords with the actual regex
strings used by the script) so the table entries for Docs-only and Code match
the implementation.
🧹 Nitpick comments (7)
.agent/scripts/pre-edit-check.sh (3)
33-47: Validate that --task accompanies --loop-mode.When
--loop-modeis specified without--task, the script will pass an empty string tois_docs_only(), which will always return 1 (not docs-only) and trigger worktree creation. This could be unexpected behavior.🔍 Add validation to ensure --task is provided with --loop-mode
After the argument parsing loop (after line 47), add:
done + +# Validate loop mode requirements +if [[ "$LOOP_MODE" == "true" && -z "$TASK_DESC" ]]; then + echo -e "${RED}ERROR${NC}: --loop-mode requires --task argument" >&2 + exit 1 +fi
49-74: Consider extracting pattern constants for maintainability.The regex patterns for code and docs detection are embedded in the function as strings. As the list of keywords grows (especially with new patterns like "port", "ssl", "helper"), maintaining these inline strings becomes harder.
♻️ Extract patterns as readonly constants
Before the
is_docs_only()function definition (around line 48):+# Task classification patterns +readonly DOCS_ONLY_PATTERNS="^readme|^changelog|^documentation|docs/|typo|spelling|comment only|license only|^update readme|^update changelog|^update docs" +readonly CODE_TASK_PATTERNS="feature|fix|bug|implement|refactor|add.*function|update.*code|create.*script|modify.*config|change.*logic|new.*api|endpoint|enhance|port|ssl|helper" + # Function to detect if task is docs-only is_docs_only() { local task="$1" local task_lower task_lower=$(echo "$task" | tr '[:upper:]' '[:lower:]') - # Code change indicators (negative match - if present, NOT docs-only) - # These take precedence over docs patterns - 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" - # Check for code patterns first (takes precedence) - if echo "$task_lower" | grep -qE "$code_patterns"; then + if echo "$task_lower" | grep -qE "$CODE_TASK_PATTERNS"; then return 1 # Not docs-only fi # Check for docs patterns - if echo "$task_lower" | grep -qE "$docs_patterns"; then + if echo "$task_lower" | grep -qE "$DOCS_ONLY_PATTERNS"; then return 0 # Is docs-only fi
52-53: Minor:trcommand is locale-dependent.Using
tr '[:upper:]' '[:lower:]'can have unexpected behavior in some locales. For a more portable approach, consider using shell parameter expansion or ensuringLC_ALL=C.🌐 Make case conversion locale-safe
- task_lower=$(echo "$task" | tr '[:upper:]' '[:lower:]') + task_lower=$(echo "$task" | LC_ALL=C tr '[:upper:]' '[:lower:]')Alternatively, use Bash 4+ parameter expansion:
- task_lower=$(echo "$task" | tr '[:upper:]' '[:lower:]') + task_lower="${task,,}".agent/scripts/localhost-helper.sh (3)
68-88: Enhance port checking reliability with better nc usage.The current
nc -zcheck on line 82 may not work consistently across all platforms (macOS vs Linux have differentncimplementations). Additionally, the function returns success whenlsofsucceeds but doesn't check its exit code explicitly.🔧 Improve cross-platform port checking
is_port_free() { local port="$1" if [[ -z "$port" ]]; then print_error "Port number required" return 1 fi # Check using lsof (works on macOS and Linux) if lsof -i :"$port" >/dev/null 2>&1; then return 1 # Port is in use fi - # Double-check with nc if available - if command -v nc >/dev/null 2>&1; then - if nc -z 127.0.0.1 "$port" 2>/dev/null; then - return 1 # Port is in use - fi - fi + # Double-check with platform-specific nc if available + if command -v nc >/dev/null 2>&1; then + # Use timeout to avoid hanging; -w1 works on both Linux and macOS BSD nc + if timeout 1 nc -z 127.0.0.1 "$port" 2>/dev/null; then + return 1 # Port is in use + fi + fi return 0 # Port is free }Note:
timeoutcommand may not be available on all systems. Consider wrapping in a check or using shell built-in timeout alternatives.
93-107: Consider adding a max iteration safety check.If all ports in the range are occupied, the function correctly returns an error. However, for very large ranges, this could take a long time. Consider logging progress for ranges > 1000 ports.
📊 Add progress indication for large scans
find_available_port() { local start_port="${1:-$PORT_RANGE_START}" local port="$start_port" + local range_size=$((PORT_RANGE_END - start_port)) + + if [[ $range_size -gt 1000 ]]; then + print_info "Scanning large port range ($range_size ports), this may take a moment..." + fi while [[ $port -le $PORT_RANGE_END ]]; do if is_port_free "$port"; then echo "$port" return 0 fi ((port++)) done
139-157: Hard-coded port list may miss user's actual dev ports.The list on line 144 is a reasonable set of common dev ports, but users may have services on other ports. Consider enhancing this to scan a broader range or allow configuration.
🔍 Optionally scan broader range or check config
list_dev_ports() { print_info "Ports in use by local development services:" echo "" - # Common development port ranges - local dev_ports="3000 3001 3002 3003 4000 5000 5173 5174 8000 8080 8085 8888 9000 9222 11235" + # Common development port ranges (can be overridden via config) + local dev_ports="${DEV_PORTS_TO_CHECK:-3000 3001 3002 3003 4000 5000 5173 5174 8000 8080 8085 8888 9000 9222 11235}" for port in $dev_ports; do if ! is_port_free "$port"; then local process_info process_info=$(lsof -i :"$port" 2>/dev/null | tail -1 | awk '{print $1}') echo " :$port - $process_info" fi done echo "" print_info "Use 'lsof -i :<port>' for detailed process info" + print_info "Set DEV_PORTS_TO_CHECK env var to customize port list" return 0 }.agent/scripts/commands/full-loop.md (1)
44-46: Branch name sanitization logic could produce empty or problematic names.The branch name generation on lines 44-46 has potential edge cases:
- If
$ARGUMENTScontains only special characters, the result could be a string of dashes or empty- No validation that the resulting branch name is valid
- Consecutive dashes aren't collapsed
🔧 Enhance branch name sanitization
# Generate branch name from task (sanitized, truncated to 40 chars) -branch_name=$(echo "$ARGUMENTS" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | cut -c1-40) +branch_name=$(echo "$ARGUMENTS" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//' | cut -c1-40) + +# Validate branch name +if [[ -z "$branch_name" || "$branch_name" == "-" ]]; then + branch_name="feature-$(date +%Y%m%d-%H%M%S)" + echo "Warning: Could not generate meaningful branch name from task, using: $branch_name" +fi + ~/.aidevops/agents/scripts/worktree-helper.sh add "feature/$branch_name"This:
- Collapses multiple consecutive dashes to single dash
- Strips leading/trailing dashes
- Falls back to timestamp-based name if sanitization produces empty/invalid result
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
.agent/AGENTS.md.agent/scripts/commands/full-loop.md.agent/scripts/localhost-helper.sh.agent/scripts/pre-edit-check.sh.agent/services/hosting/localhost.md.agent/workflows/ralph-loop.md
🧰 Additional context used
📓 Path-based instructions (1)
.agent/scripts/*.sh
⚙️ CodeRabbit configuration file
.agent/scripts/*.sh: Automation scripts - focus on:
- Reliability and robustness
- Clear logging and feedback
- Proper exit codes
- Error recovery mechanisms
Files:
.agent/scripts/pre-edit-check.sh.agent/scripts/localhost-helper.sh
🧠 Learnings (9)
📚 Learning: 2025-11-29T04:34:42.033Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENT.md:0-0
Timestamp: 2025-11-29T04:34:42.033Z
Learning: Reference AGENTS.md (authoritative) instead of AGENT.md for AI assistant guidance
Applied to files:
.agent/AGENTS.md
📚 Learning: 2026-01-06T15:57:56.008Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-06T15:57:56.008Z
Learning: Applies to **/AGENTS.md : Limit root AGENTS.md to ~50-100 max instructions with universal applicability to >80% of tasks
Applied to files:
.agent/AGENTS.md
📚 Learning: 2025-11-29T04:34:27.158Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-29T04:34:27.158Z
Learning: All instructions, documentation, and operational guidance should be maintained in AGENTS.md as the single source of truth
Applied to files:
.agent/AGENTS.md
📚 Learning: 2025-11-29T04:34:30.742Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-11-29T04:34:30.742Z
Learning: Reference AGENTS.md for authoritative AI assistant guidance instead of GEMINI.md
Applied to files:
.agent/AGENTS.md
📚 Learning: 2025-11-29T04:34:30.742Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-11-29T04:34:30.742Z
Learning: Maintain all instructions, documentation, and operational guidance in AGENTS.md as the single source of truth
Applied to files:
.agent/AGENTS.md
📚 Learning: 2026-01-06T15:57:56.008Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-06T15:57:56.008Z
Learning: Applies to **/AGENTS.md : Include code examples in AGENTS.md only when authoritative, otherwise use file:line references
Applied to files:
.agent/AGENTS.md
📚 Learning: 2025-12-22T01:24:53.937Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: templates/home/AGENTS.md:0-0
Timestamp: 2025-12-22T01:24:53.937Z
Learning: Follow all security protocols and working directory specifications defined in ~/Git/aidevops/AGENTS.md
Applied to files:
.agent/AGENTS.md.agent/scripts/commands/full-loop.md
📚 Learning: 2026-01-06T15:57:56.007Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-06T15:57:56.007Z
Learning: Applies to **/.agent/scripts/linters-local.sh : Run quality checks before committing using .agent/scripts/linters-local.sh
Applied to files:
.agent/AGENTS.md.agent/scripts/pre-edit-check.sh.agent/scripts/commands/full-loop.md
📚 Learning: 2026-01-06T15:57:56.008Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-06T15:57:56.008Z
Learning: Maintain SonarCloud A-grade quality standard
Applied to files:
.agent/AGENTS.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (12)
.agent/scripts/pre-edit-check.sh (1)
99-111: LGTM: Loop mode logic is clear and well-structured.The exit codes are well-defined, the output messages are helpful for debugging, and the
LOOP_DECISIONoutput provides a parseable signal for calling scripts. The precedence of code patterns over docs patterns is correctly implemented..agent/scripts/localhost-helper.sh (2)
18-24: LGTM: Conditional constant definitions prevent conflicts.This pattern gracefully handles both standalone execution and sourcing from shared-constants.sh. The
-zchecks ensure constants aren't redefined if already set.
677-688: LGTM: Command dispatch follows existing pattern.The new port management commands are cleanly integrated into the existing case structure, and parameter passing is consistent with other commands.
.agent/workflows/ralph-loop.md (1)
78-99: LGTM: Documentation accurately reflects the implementation.The auto-branch handling documentation correctly describes the loop-mode behavior, exit codes, and task classification logic implemented in
pre-edit-check.sh. The table format makes the detection rules clear and easy to reference..agent/AGENTS.md (3)
45-60: LGTM: Loop mode guidance integrates well with existing pre-edit check section.The autonomous loop mode documentation is placed logically after the manual pre-edit check workflow, and the exit codes and auto-decision rules align with the
pre-edit-check.shimplementation.
52-59: Same keyword sync concern as ralph-loop.md.The detection keywords listed here should stay synchronized with the actual regex patterns in
pre-edit-check.sh. The implementation has more comprehensive patterns than shown in this simplified list.Consider establishing a single source of truth for these keywords. Options:
- Documentation simplification (current approach): Show representative keywords, accept that docs won't list every pattern variant
- Pattern extraction: Generate docs from the actual regex patterns in the script
- Shared constants: Move patterns to shared-constants.sh and reference from both script and docs
Since the implementation patterns were just reviewed in pre-edit-check.sh with a suggestion to extract them as constants, Option 3 would provide the best long-term maintainability.
112-118: LGTM: Localhost standards are clear and actionable.The new localhost standards section provides concrete guidance with specific commands, explains the rationale (.local domains for password managers, SSL for security), and references the full guide. The note about SonarCloud exclusions is helpful context.
.agent/scripts/commands/full-loop.md (2)
19-48: LGTM: Auto-branch setup documentation is comprehensive.The step-by-step flow clearly explains the automated branch handling, exit codes, and when worktrees are created. The verification steps (clean working directory, git remote) are important checks.
37-39: Keyword list consistency across documentation.This file lists the same detection keywords as
ralph-loop.mdandAGENTS.md. All three docs should stay synchronized with the implementation inpre-edit-check.sh.As suggested in the review of
pre-edit-check.sh, consider extracting the patterns as constants inshared-constants.sh. Then documentation can reference or generate from the canonical source, ensuring consistency.This is a maintainability concern rather than a current bug, but worth addressing to prevent docs and implementation from diverging over time as new keywords are added.
.agent/services/hosting/localhost.md (3)
18-47: Excellent rationale and workflow clarity.The CRITICAL section effectively justifies the .local + SSL + port management approach with clear problem/solution mapping and concrete workflow example. Password manager compatibility (1Password/Bitwarden HTTPS requirement) is a strong motivator that many developers miss.
However, verify that the quick reference command list (line 22) is accurate and complete. The Usage Examples section (lines 206–215) references
generate-ssl,install-ssl,list-ssl, andrenew-ssl, but the quick reference only listsgenerate-cert. Ensure command names are consistent across the document.
53-97: Clear, well-structured problem/solution narrative.The progression from "Problem with
localhost:port" → "Solution: .local + SSL + Port Checking" → "Standard Workflow" is logical and persuasive. The tables effectively map components to tools and benefits. Developers will understand both the what and the why.
218-232: Port Management section is well-documented.The new port management commands are clearly explained with practical examples. However, ensure the Quick Reference (line 22) and this section both list
find-port(mentioned in PR objectives but less prominent in the command list). Also verifyforward-port(line 231) is actually implemented, as it wasn't mentioned in the PR objectives.
| kill_port() { | ||
| local port="$1" | ||
|
|
||
| if [[ -z "$port" ]]; then | ||
| print_error "Port number required" | ||
| return 1 | ||
| fi | ||
|
|
||
| local pids | ||
| pids=$(lsof -ti :"$port" 2>/dev/null) | ||
|
|
||
| if [[ -z "$pids" ]]; then | ||
| print_info "No process found on port $port" | ||
| return 0 | ||
| fi | ||
|
|
||
| print_warning "Killing process(es) on port $port: $pids" | ||
| echo "$pids" | xargs kill -9 2>/dev/null | ||
|
|
||
| sleep 1 | ||
| if is_port_free "$port"; then | ||
| print_success "Port $port is now free" | ||
| return 0 | ||
| else | ||
| print_error "Failed to free port $port" | ||
| return 1 | ||
| fi | ||
| } |
There was a problem hiding this comment.
Critical: kill -9 is destructive and should confirm before execution.
The kill_port function uses kill -9 (SIGKILL) which forcefully terminates processes without allowing cleanup. This could lead to data loss or corrupted state for services like databases.
⚠️ Add confirmation prompt and try graceful kill first
kill_port() {
local port="$1"
if [[ -z "$port" ]]; then
print_error "Port number required"
return 1
fi
local pids
pids=$(lsof -ti :"$port" 2>/dev/null)
if [[ -z "$pids" ]]; then
print_info "No process found on port $port"
return 0
fi
- print_warning "Killing process(es) on port $port: $pids"
- echo "$pids" | xargs kill -9 2>/dev/null
+ # Show process details
+ local process_info
+ process_info=$(lsof -i :"$port" 2>/dev/null | tail -n +2)
+ print_warning "Process(es) using port $port:"
+ echo "$process_info"
+ echo ""
+
+ # Confirm before killing
+ read -p "Kill these processes? (y/N) " -n 1 -r
+ echo ""
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ print_info "Cancelled"
+ return 1
+ fi
+
+ # Try graceful kill first (SIGTERM)
+ print_info "Attempting graceful shutdown (SIGTERM)..."
+ echo "$pids" | xargs kill 2>/dev/null
+
+ sleep 2
+
+ # Check if still running
+ local remaining_pids
+ remaining_pids=$(lsof -ti :"$port" 2>/dev/null)
+
+ if [[ -n "$remaining_pids" ]]; then
+ print_warning "Processes still running, forcing kill (SIGKILL)..."
+ echo "$remaining_pids" | xargs kill -9 2>/dev/null
+ fi
sleep 1
if is_port_free "$port"; then
print_success "Port $port is now free"
return 0
else
print_error "Failed to free port $port"
return 1
fi
}Alternatively, add a --force flag to skip confirmation for scripted usage.
🤖 Prompt for AI Agents
In @.agent/scripts/localhost-helper.sh around lines 160 - 187, The kill_port
function currently uses kill -9 unconditionally; modify kill_port to prompt for
confirmation (unless a new --force flag or FORCED=true env is passed) before
killing, attempt a graceful kill first (kill PID with SIGTERM), wait/recheck
with is_port_free, and only if still occupied then escalate to SIGKILL and log
the escalation via print_warning/print_error/print_success; ensure the
confirmation prompt references the PIDs and port, and make non-interactive
scripts possible by honoring the --force flag or environment variable so callers
can skip confirmation.
| | Task Type | Detection Keywords | Action | | ||
| |-----------|-------------------|--------| | ||
| | Docs-only | readme, changelog, docs/, documentation, typo, spelling | Stay on main (exit 0) | | ||
| | Code | feature, fix, bug, implement, refactor, add, update, enhance | Create worktree (exit 2) | |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Extract and compare patterns from implementation vs documentation
echo "=== Checking pre-edit-check.sh patterns ==="
if [ -f ".agent/scripts/pre-edit-check.sh" ]; then
echo "File found. Extracting pattern variables:"
grep -E "(code_patterns=|docs_patterns=)" ".agent/scripts/pre-edit-check.sh" -A 1
else
echo "File not found at .agent/scripts/pre-edit-check.sh"
fi
echo ""
echo "=== Checking ralph-loop.md keywords table ==="
if [ -f ".agent/workflows/ralph-loop.md" ]; then
echo "File found. Extracting relevant table rows:"
sed -n '89,92p' ".agent/workflows/ralph-loop.md"
else
echo "File not found at .agent/workflows/ralph-loop.md"
fi
echo ""
echo "=== Directory structure check ==="
ls -la .agent/scripts/ 2>/dev/null || echo "Scripts directory not found"
ls -la .agent/workflows/ 2>/dev/null || echo "Workflows directory not found"Repository: marcusquinn/aidevops
Length of output: 11511
Update documentation keywords to match implementation patterns.
The keyword table in ralph-loop.md is incomplete. The actual patterns in pre-edit-check.sh include additional detection rules not currently documented:
Missing docs-only patterns: comment only, license only, ^update readme, ^update changelog, ^update docs
Missing code patterns: add.*function, update.*code, create.*script, modify.*config, change.*logic, new.*api, endpoint, port, ssl, helper
Update the table to either list the complete regex patterns or expand the keyword list to maintain sync with the implementation. This ensures developers understand the full scope of what triggers task type detection.
🤖 Prompt for AI Agents
In @.agent/workflows/ralph-loop.md around lines 89 - 92, The docs table in
ralph-loop.md is missing several detection patterns present in
pre-edit-check.sh; update the Task Type table so the "Detection Keywords" column
contains the full regex patterns (or expanded keyword lists) used by
pre-edit-check.sh — specifically add docs-only patterns: "comment only",
"license only", "^update readme", "^update changelog", "^update docs"; and add
code patterns like "add.*function", "update.*code", "create.*script",
"modify.*config", "change.*logic", "new.*api", "endpoint", "port", "ssl",
"helper" (or replace the simple keywords with the actual regex strings used by
the script) so the table entries for Docs-only and Code match the
implementation.
|
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Sun Jan 11 16:41:59 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
🤖 Augment PR SummarySummary: This PR improves autonomous agent workflows and local dev ergonomics by adding non-interactive branch decisions and port conflict handling. Changes:
Technical Notes: Loop-mode communicates decisions via 🤖 Was this summary useful? React with 👍 or 👎 |
| shift | ||
| ;; | ||
| --task) | ||
| TASK_DESC="$2" |
| # Check if a port is in use | ||
| # Returns 0 if port is FREE, 1 if port is IN USE | ||
| is_port_free() { | ||
| local port="$1" |
There was a problem hiding this comment.
is_port_free treats failures to run lsof/nc (e.g., missing command or non-numeric port) as “port is free” because it just falls through. Consider validating port is an integer and returning an error when checks can’t be performed to avoid false “available” results and downstream arithmetic/comparison failures.
🤖 Was this useful? React with 👍 or 👎
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
.agent/scripts/localhost-helper.sh (1)
641-741: Critical:main()always returns 0, so new port commands can’t signal failure/success.This breaks the advertised semantics of:
check-port(should return 0 free / 1 in-use)find-port(should return non-zero when none found)kill-port(should return non-zero on failure)Proposed fix
esac -return 0 +return $? }As per coding guidelines, automation scripts must have reliable exit codes.
.agent/services/hosting/localhost.md (1)
129-155: Doc inconsistency: MCP port is 8085 in text but 3001 in the config snippet.Line 23 says MCP on 8085, but the JSON example still shows
"mcp_port": 3001(Line 139). That’s a footgun.Proposed fix
"mcp_enabled": true, - "mcp_port": 3001 + "mcp_port": 8085
🤖 Fix all issues with AI agents
In @.agent/scripts/localhost-helper.sh:
- Around line 18-24: The script currently defines fallbacks for
ERROR_UNKNOWN_COMMAND and HELP_USAGE_INFO but other constants used (e.g.,
ERROR_CONFIG_NOT_FOUND referenced in check_config()) are not defined when
shared-constants.sh is missing, producing unclear errors; update the top of the
script to attempt sourcing shared-constants.sh and, if absent, provide clear
fallback readonly definitions for every constant the script references (at
minimum ERROR_CONFIG_NOT_FOUND and any ERROR_INVALID_CONFIG /
ERROR_MISSING_DEPENDENCY or HELP_* tokens used elsewhere), and ensure
check_config() and other functions use those fallbacks so error messages are
always informative.
- Around line 62-136: The port helpers assume lsof exists and accept any input;
update is_port_free(), find_available_port(), and check_port_or_suggest() (and
list_dev_ports()) to: 1) validate the port argument is numeric and within
1–65535 (use a digits regex and numeric bounds) and return error if not, 2)
guard all lsof usages with a command -v lsof >/dev/null 2>&1 check before
invoking it (fall back to nc or skip lsof output if unavailable), and 3) ensure
find_available_port only iterates when start_port is valid so downstream
arithmetic like ((port++)) or $((port+1)) never runs on invalid input; apply the
same guarded lsof pattern in list_dev_ports() and surface clear error messages
when tools are missing or ports are invalid.
In @.agent/scripts/pre-edit-check.sh:
- Around line 33-47: The flag parsing loop can crash under set -u because --task
uses an unset $2; update the while/case that handles --task to first verify a
non-empty next argument exists and is not another flag before assigning
TASK_DESC, and if missing print a clear error and exit nonzero; also change the
default case (currently *) to treat unknown flags as errors (print the flag name
and exit) rather than silently shifting so failures are deterministic.
🧹 Nitpick comments (2)
.agent/scripts/localhost-helper.sh (1)
160-190: Avoid defaulting tokill -9; try SIGTERM then escalate (less collateral damage).For dev ergonomics and safety, terminate gracefully first, then SIGKILL only if the port doesn’t clear.
Proposed fix
print_warning "Killing process(es) on port $port: $pids" - echo "$pids" | xargs kill -9 2>/dev/null + echo "$pids" | xargs kill 2>/dev/null || true # Wait up to 3 seconds for the port to become free for _ in {1..6}; do if is_port_free "$port"; then print_success "Port $port is now free" return 0 fi sleep 0.5 done + + print_warning "Escalating to SIGKILL for port $port: $pids" + echo "$pids" | xargs kill -9 2>/dev/null || true + for _ in {1..6}; do + if is_port_free "$port"; then + print_success "Port $port is now free" + return 0 + fi + sleep 0.5 + done print_error "Failed to free port $port" return 1 }.agent/services/hosting/localhost.md (1)
22-48: Quick Reference + Standard Setup Pattern are actionable and match the new command surface.Nice job making the “check → find → create-app” flow copy/pasteable.
Consider using a single canonical invocation style throughout (either always
localhost-helper.sh ...if it’s on PATH, or always~/.aidevops/agents/scripts/localhost-helper.sh ...) to reduce setup ambiguity.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
.agent/scripts/localhost-helper.sh.agent/scripts/pre-edit-check.sh.agent/services/hosting/localhost.md
🧰 Additional context used
📓 Path-based instructions (1)
.agent/scripts/*.sh
⚙️ CodeRabbit configuration file
.agent/scripts/*.sh: Automation scripts - focus on:
- Reliability and robustness
- Clear logging and feedback
- Proper exit codes
- Error recovery mechanisms
Files:
.agent/scripts/pre-edit-check.sh.agent/scripts/localhost-helper.sh
🧬 Code graph analysis (1)
.agent/scripts/localhost-helper.sh (2)
.agent/scripts/find-missing-returns.sh (1)
print_error(21-25).agent/scripts/pagespeed-helper.sh (1)
print_success(20-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (3)
.agent/scripts/localhost-helper.sh (1)
680-716: Command wiring + help text for port management looks solid.The dispatcher entries and usage text are clear and match the new functions.
.agent/scripts/pre-edit-check.sh (1)
99-111: Loop-mode decisioning + exit codes are clear and automation-friendly.
LOOP_DECISION=stay/worktreeplus exit codes 0/2 is a clean contract for loop agents..agent/services/hosting/localhost.md (1)
53-97: Rationale section is crisp and ties directly to dev pain (ports, password managers, SSL testing).This will help prevent “random localhost:NNNN” drift across projects.
| # Error message constants (use shared-constants.sh if available, otherwise define locally) | ||
| if [[ -z "${ERROR_UNKNOWN_COMMAND:-}" ]]; then | ||
| readonly ERROR_UNKNOWN_COMMAND="Unknown command:" | ||
| fi | ||
| if [[ -z "${HELP_USAGE_INFO:-}" ]]; then | ||
| readonly HELP_USAGE_INFO="Use '$0 help' for usage information" | ||
| fi |
There was a problem hiding this comment.
Fallback constants are incomplete (shared-constants absent => confusing errors).
You added fallbacks for ERROR_UNKNOWN_COMMAND / HELP_USAGE_INFO, but the script also uses other constants (e.g., ERROR_CONFIG_NOT_FOUND in check_config()). If shared-constants.sh isn’t present, error output becomes blank-ish.
Proposed fix
if [[ -z "${ERROR_UNKNOWN_COMMAND:-}" ]]; then
readonly ERROR_UNKNOWN_COMMAND="Unknown command:"
fi
if [[ -z "${HELP_USAGE_INFO:-}" ]]; then
readonly HELP_USAGE_INFO="Use '$0 help' for usage information"
fi
+if [[ -z "${ERROR_CONFIG_NOT_FOUND:-}" ]]; then
+ readonly ERROR_CONFIG_NOT_FOUND="Config file not found:"
+fiAs per coding guidelines, automation scripts should fail with clear, actionable messaging.
📝 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.
| # Error message constants (use shared-constants.sh if available, otherwise define locally) | |
| if [[ -z "${ERROR_UNKNOWN_COMMAND:-}" ]]; then | |
| readonly ERROR_UNKNOWN_COMMAND="Unknown command:" | |
| fi | |
| if [[ -z "${HELP_USAGE_INFO:-}" ]]; then | |
| readonly HELP_USAGE_INFO="Use '$0 help' for usage information" | |
| fi | |
| # Error message constants (use shared-constants.sh if available, otherwise define locally) | |
| if [[ -z "${ERROR_UNKNOWN_COMMAND:-}" ]]; then | |
| readonly ERROR_UNKNOWN_COMMAND="Unknown command:" | |
| fi | |
| if [[ -z "${HELP_USAGE_INFO:-}" ]]; then | |
| readonly HELP_USAGE_INFO="Use '$0 help' for usage information" | |
| fi | |
| if [[ -z "${ERROR_CONFIG_NOT_FOUND:-}" ]]; then | |
| readonly ERROR_CONFIG_NOT_FOUND="Config file not found:" | |
| fi |
🤖 Prompt for AI Agents
In @.agent/scripts/localhost-helper.sh around lines 18 - 24, The script
currently defines fallbacks for ERROR_UNKNOWN_COMMAND and HELP_USAGE_INFO but
other constants used (e.g., ERROR_CONFIG_NOT_FOUND referenced in check_config())
are not defined when shared-constants.sh is missing, producing unclear errors;
update the top of the script to attempt sourcing shared-constants.sh and, if
absent, provide clear fallback readonly definitions for every constant the
script references (at minimum ERROR_CONFIG_NOT_FOUND and any
ERROR_INVALID_CONFIG / ERROR_MISSING_DEPENDENCY or HELP_* tokens used
elsewhere), and ensure check_config() and other functions use those fallbacks so
error messages are always informative.
| # Default port range for auto-assignment | ||
| readonly PORT_RANGE_START=3000 | ||
| readonly PORT_RANGE_END=9999 | ||
|
|
||
| # Check if a port is in use | ||
| # Returns 0 if port is FREE, 1 if port is IN USE | ||
| is_port_free() { | ||
| local port="$1" | ||
| if [[ -z "$port" ]]; then | ||
| print_error "Port number required" | ||
| return 1 | ||
| fi | ||
|
|
||
| # Check using lsof (works on macOS and Linux) | ||
| if lsof -i :"$port" >/dev/null 2>&1; then | ||
| return 1 # Port is in use | ||
| fi | ||
|
|
||
| # Double-check with nc if available | ||
| if command -v nc >/dev/null 2>&1; then | ||
| if nc -z 127.0.0.1 "$port" 2>/dev/null; then | ||
| return 1 # Port is in use | ||
| fi | ||
| fi | ||
|
|
||
| return 0 # Port is free | ||
| } | ||
|
|
||
| # Find the next available port starting from a given port | ||
| # Usage: find_available_port [start_port] | ||
| # Returns: Prints the first available port | ||
| find_available_port() { | ||
| local start_port="${1:-$PORT_RANGE_START}" | ||
| local port="$start_port" | ||
|
|
||
| while [[ $port -le $PORT_RANGE_END ]]; do | ||
| if is_port_free "$port"; then | ||
| echo "$port" | ||
| return 0 | ||
| fi | ||
| ((port++)) | ||
| done | ||
|
|
||
| print_error "No available ports found in range $start_port-$PORT_RANGE_END" | ||
| return 1 | ||
| } | ||
|
|
||
| # Check port and suggest alternative if in use | ||
| # Usage: check_port_or_suggest [port] | ||
| # Returns: 0 if port is free, 1 if in use (prints suggestion) | ||
| check_port_or_suggest() { | ||
| local port="$1" | ||
|
|
||
| if [[ -z "$port" ]]; then | ||
| print_error "Port number required" | ||
| return 1 | ||
| fi | ||
|
|
||
| if is_port_free "$port"; then | ||
| print_success "Port $port is available" | ||
| return 0 | ||
| else | ||
| local process_info | ||
| process_info=$(lsof -i :"$port" 2>/dev/null | tail -1 | awk '{print $1, $2}') | ||
| print_warning "Port $port is in use by: $process_info" | ||
|
|
||
| local suggested_port | ||
| suggested_port=$(find_available_port "$((port + 1))") | ||
| if [[ -n "$suggested_port" ]]; then | ||
| print_info "Suggested alternative: $suggested_port" | ||
| echo "SUGGESTED_PORT=$suggested_port" | ||
| fi | ||
| return 1 | ||
| fi | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's verify the current state of the file and examine lines 62-136
cat -n .agent/scripts/localhost-helper.sh | head -150Repository: marcusquinn/aidevops
Length of output: 5547
🏁 Script executed:
# Check if there's any bootstrap or setup script that documents tool availability
fd -t f -e sh -e bash | head -20Repository: marcusquinn/aidevops
Length of output: 776
🏁 Script executed:
# Look for any environment setup or requirements documentation
git ls-files | grep -E "(README|setup|bootstrap|requirements|install)" | head -10Repository: marcusquinn/aidevops
Length of output: 421
🏁 Script executed:
# Check if there are other scripts that validate tool availability
rg -t sh "lsof|command -v" --max-count=20 -A 2 -B 2Repository: marcusquinn/aidevops
Length of output: 50376
Add input validation and tool availability guards to port helper functions
The port management functions assume lsof is available but don't verify it—on systems without lsof, checks silently pass or output noise. Additionally, port parameters lack validation, risking arithmetic errors when non-numeric input reaches $((port+1)) or ((port++)).
Three instances require fixing:
is_port_free()line 76: callslsofwithout checking availability (inconsistent with thencfallback check on line 81)check_port_or_suggest()line 125: callslsofdirectly without guardlist_dev_ports()line 149: callslsofdirectly without guard
Add numeric port validation (1–65535) in is_port_free() and find_available_port() to prevent downstream arithmetic failures. This aligns with the codebase pattern: 80+ scripts defensively check tool availability with if ! command -v <tool> >/dev/null 2>&1; then before use.
🤖 Prompt for AI Agents
In @.agent/scripts/localhost-helper.sh around lines 62 - 136, The port helpers
assume lsof exists and accept any input; update is_port_free(),
find_available_port(), and check_port_or_suggest() (and list_dev_ports()) to: 1)
validate the port argument is numeric and within 1–65535 (use a digits regex and
numeric bounds) and return error if not, 2) guard all lsof usages with a command
-v lsof >/dev/null 2>&1 check before invoking it (fall back to nc or skip lsof
output if unavailable), and 3) ensure find_available_port only iterates when
start_port is valid so downstream arithmetic like ((port++)) or $((port+1))
never runs on invalid input; apply the same guarded lsof pattern in
list_dev_ports() and surface clear error messages when tools are missing or
ports are invalid.
| while [[ $# -gt 0 ]]; do | ||
| case $1 in | ||
| --loop-mode) | ||
| LOOP_MODE=true | ||
| shift | ||
| ;; | ||
| --task) | ||
| TASK_DESC="$2" | ||
| shift 2 | ||
| ;; | ||
| *) | ||
| shift | ||
| ;; | ||
| esac | ||
| done |
There was a problem hiding this comment.
Harden --task parsing (currently can crash under set -u).
--task without a value will expand $2 while unset. Fail fast with a clear message (and consider rejecting unknown flags rather than silently ignoring them).
Proposed fix
--task)
- TASK_DESC="$2"
- shift 2
+ if [[ $# -lt 2 ]]; then
+ echo "ERROR: --task requires a value" >&2
+ exit 1
+ fi
+ TASK_DESC="$2"
+ shift 2
;;
*)
- shift
+ echo "WARNING: ignoring unknown arg: $1" >&2
+ shift
;;As per coding guidelines, automation scripts should fail deterministically with clear feedback.
📝 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.
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| --loop-mode) | |
| LOOP_MODE=true | |
| shift | |
| ;; | |
| --task) | |
| TASK_DESC="$2" | |
| shift 2 | |
| ;; | |
| *) | |
| shift | |
| ;; | |
| esac | |
| done | |
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| --loop-mode) | |
| LOOP_MODE=true | |
| shift | |
| ;; | |
| --task) | |
| if [[ $# -lt 2 ]]; then | |
| echo "ERROR: --task requires a value" >&2 | |
| exit 1 | |
| fi | |
| TASK_DESC="$2" | |
| shift 2 | |
| ;; | |
| *) | |
| echo "WARNING: ignoring unknown arg: $1" >&2 | |
| shift | |
| ;; | |
| esac | |
| done |
🤖 Prompt for AI Agents
In @.agent/scripts/pre-edit-check.sh around lines 33 - 47, The flag parsing loop
can crash under set -u because --task uses an unset $2; update the while/case
that handles --task to first verify a non-empty next argument exists and is not
another flag before assigning TASK_DESC, and if missing print a clear error and
exit nonzero; also change the default case (currently *) to treat unknown flags
as errors (print the flag name and exit) rather than silently shifting so
failures are deterministic.
| # Function to detect if task is docs-only | ||
| is_docs_only() { | ||
| local task="$1" | ||
| # Use bash 4.0+ parameter expansion for lowercase (more efficient than tr) | ||
| local task_lower="${task,,}" | ||
|
|
||
| # Code change indicators (negative match - if present, NOT docs-only) | ||
| # These take precedence over docs patterns | ||
| 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" | ||
|
|
||
| # Check for code patterns first (takes precedence) | ||
| if echo "$task_lower" | grep -qE "$code_patterns"; then | ||
| return 1 # Not docs-only | ||
| fi | ||
|
|
||
| # Check for docs patterns | ||
| if echo "$task_lower" | grep -qE "$docs_patterns"; then | ||
| return 0 # Is docs-only | ||
| fi | ||
|
|
||
| # Default: not docs-only (safer to create branch) | ||
| return 1 | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check the shebang and overall structure of the script
head -20 .agent/scripts/pre-edit-check.shRepository: marcusquinn/aidevops
Length of output: 958
🏁 Script executed:
# Search for any documentation about Bash version requirements
find . -type f \( -name "*.md" -o -name "*.txt" -o -name "README*" \) | xargs grep -l "bash" -i | head -10Repository: marcusquinn/aidevops
Length of output: 457
🏁 Script executed:
# Check other scripts in the .agent/scripts directory for patterns
ls -la .agent/scripts/*.sh | head -20Repository: marcusquinn/aidevops
Length of output: 1776
🏁 Script executed:
# Examine shebang lines across all scripts
for script in .agent/scripts/*.sh; do
echo "=== $script ==="
head -1 "$script"
doneRepository: marcusquinn/aidevops
Length of output: 6876
🏁 Script executed:
# Look for Bash version checks or requirements in the codebase
rg "bash.*4|version.*bash|BASH_VERSION" --type sh -A 2 -B 2Repository: marcusquinn/aidevops
Length of output: 921
🏁 Script executed:
# Check CI configuration files for environment specifications
find . -type f \( -name ".github" -o -name "*.yml" -o -name "*.yaml" \) -path "*/.github/*" | head -20Repository: marcusquinn/aidevops
Length of output: 342
🏁 Script executed:
# Check CI workflow configurations for Bash/runner specifications
cat .github/workflows/code-quality.yml | head -50Repository: marcusquinn/aidevops
Length of output: 1829
🏁 Script executed:
# Get the full pre-edit-check.sh script to understand context
cat -n .agent/scripts/pre-edit-check.shRepository: marcusquinn/aidevops
Length of output: 7744
🏁 Script executed:
# Look for any Bash version checks or requirements in documentation
rg "bash.*version|minimum.*bash|bash.*3|bash.*4" -i --type md -A 2 -B 2Repository: marcusquinn/aidevops
Length of output: 5889
🏁 Script executed:
# Test the regex patterns with example task descriptions
python3 << 'EOF'
import re
import subprocess
# Simulate the is_docs_only function
def test_is_docs_only(task):
task_lower = task.lower()
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_patterns = "^readme|^changelog|^documentation|docs/|typo|spelling|comment only|license only|^update readme|^update changelog|^update docs"
# Check code patterns first
if re.search(code_patterns, task_lower):
return "NOT docs-only (code pattern match)"
# Check docs patterns
if re.search(docs_patterns, task_lower):
return "IS docs-only (docs pattern match)"
# Default
return "NOT docs-only (default)"
# Test cases
test_tasks = [
"Update docs/localhost.md for SSL", # Review's example
"Update README.md with SSL configuration",
"Fix SSL certificate docs",
"Add helper script for SSL",
"Update docs/ssl-setup.md",
"Document SSL port configuration",
"Fix typo in docs/ssl.md",
"Add SSL section to docs/README",
"Refactor SSL helper function",
"Update changelog for SSL fix",
]
print("Testing regex patterns:")
print("-" * 70)
for task in test_tasks:
result = test_is_docs_only(task)
print(f"Task: {task:<45} -> {result}")
EOFRepository: marcusquinn/aidevops
Length of output: 150
🏁 Script executed:
# Also check if there's any documentation about Bash version requirements
rg "bash.*3\.|bash.*4\.|compatibility|version.*requirement" -i --type mdRepository: marcusquinn/aidevops
Length of output: 5395
🏁 Script executed:
# Check how pre-edit-check.sh is invoked in the codebase
rg "pre-edit-check\.sh" -B 2 -A 2Repository: marcusquinn/aidevops
Length of output: 4315
🏁 Script executed:
# Manually test the regex patterns with grep
echo "Testing regex patterns:"
echo ""
# Test tasks
echo "Test 1: 'Update docs/localhost.md for SSL'"
echo "update docs/localhost.md for ssl" | grep -qE "feature|fix|bug|implement|refactor|add.*function|update.*code|create.*script|modify.*config|change.*logic|new.*api|endpoint|enhance|port|ssl|helper" && echo " → Matches CODE_PATTERNS (NOT docs-only)" || echo " → No code pattern"
echo ""
echo "Test 2: 'Update README.md with SSL configuration'"
echo "update readme.md with ssl configuration" | grep -qE "feature|fix|bug|implement|refactor|add.*function|update.*code|create.*script|modify.*config|change.*logic|new.*api|endpoint|enhance|port|ssl|helper" && echo " → Matches CODE_PATTERNS (NOT docs-only)" || echo " → No code pattern"
echo ""
echo "Test 3: 'Add helper script for SSL'"
echo "add helper script for ssl" | grep -qE "feature|fix|bug|implement|refactor|add.*function|update.*code|create.*script|modify.*config|change.*logic|new.*api|endpoint|enhance|port|ssl|helper" && echo " → Matches CODE_PATTERNS (NOT docs-only)" || echo " → No code pattern"
echo ""
echo "Test 4: 'Update docs/port-configuration.md (pure docs)'"
echo "update docs/port-configuration.md" | grep -qE "feature|fix|bug|implement|refactor|add.*function|update.*code|create.*script|modify.*config|change.*logic|new.*api|endpoint|enhance|port|ssl|helper" && echo " → Matches CODE_PATTERNS (NOT docs-only - FALSE POSITIVE)" || echo " → No code pattern"
echo ""
echo "Test 5: 'Fix localhost helper (code change)'"
echo "fix localhost helper" | grep -qE "feature|fix|bug|implement|refactor|add.*function|update.*code|create.*script|modify.*config|change.*logic|new.*api|endpoint|enhance|port|ssl|helper" && echo " → Matches CODE_PATTERNS (NOT docs-only - CORRECT)" || echo " → No code pattern"Repository: marcusquinn/aidevops
Length of output: 559
🏁 Script executed:
# Check if pre-edit-check.sh is tested and what the test expectations are
find . -name "*test*" -o -name "*spec*" | xargs grep -l "pre-edit-check\|is_docs_only" 2>/dev/null | head -10Repository: marcusquinn/aidevops
Length of output: 46
🏁 Script executed:
# Look for any Bash 3 vs 4 compatibility workarounds in the codebase
rg "tr.*lower|tolower|parameter.*expansion" -i --type shRepository: marcusquinn/aidevops
Length of output: 2129
Fix Bash 4+ incompatibility and tighten regex to eliminate false positives.
Two confirmed issues:
-
Bash 4+ required but not guaranteed:
${task,,}requires Bash 4+. On macOS,/bin/bashis 3.2 by default and will fail with syntax error. Other scripts in the codebase usetrfor Bash 3 compatibility (seesetup.sh,beads-sync-helper.sh, etc.), andkeyword-research-helper.shis explicitly noted as "bash 3.2 compatible" in CHANGELOG.md. This script needs a compatibility workaround. -
Regex patterns cause false positives: The
port|ssl|helperpatterns misclassify pure docs tasks:- "Update docs/port-configuration.md" → incorrectly routed as code task
- "Update docs/localhost.md for SSL" → incorrectly routed as code task
These contradict the stated purpose. Removing these overly-broad patterns preserves correct behavior for legitimate code tasks while eliminating false routing.
Proposed fix
Replace ${task,,} with tr for Bash 3 compatibility and tighten the code patterns:
is_docs_only() {
local task="$1"
- # Use bash 4.0+ parameter expansion for lowercase (more efficient than tr)
- local task_lower="${task,,}"
+ # Use tr for bash 3.2+ compatibility (consistent with other scripts in framework)
+ local task_lower="$(echo "$task" | tr '[:upper:]' '[:lower:]')"
# Code change indicators (negative match - if present, NOT docs-only)
# These take precedence over docs patterns
- 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"
+ local code_patterns="feature|fix|bug|implement|refactor|add.*function|update.*code|create.*script|modify.*config|change.*logic|new.*api|endpoint|enhance"
# Docs-only indicators (positive match)
local docs_patterns="^readme|^changelog|^documentation|docs/|typo|spelling|comment only|license only|^update readme|^update changelog|^update docs"📝 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.
| # Function to detect if task is docs-only | |
| is_docs_only() { | |
| local task="$1" | |
| # Use bash 4.0+ parameter expansion for lowercase (more efficient than tr) | |
| local task_lower="${task,,}" | |
| # Code change indicators (negative match - if present, NOT docs-only) | |
| # These take precedence over docs patterns | |
| 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" | |
| # Check for code patterns first (takes precedence) | |
| if echo "$task_lower" | grep -qE "$code_patterns"; then | |
| return 1 # Not docs-only | |
| fi | |
| # Check for docs patterns | |
| if echo "$task_lower" | grep -qE "$docs_patterns"; then | |
| return 0 # Is docs-only | |
| fi | |
| # Default: not docs-only (safer to create branch) | |
| return 1 | |
| } | |
| # Function to detect if task is docs-only | |
| is_docs_only() { | |
| local task="$1" | |
| # Use tr for bash 3.2+ compatibility (consistent with other scripts in framework) | |
| local task_lower="$(echo "$task" | tr '[:upper:]' '[:lower:]')" | |
| # Code change indicators (negative match - if present, NOT docs-only) | |
| # These take precedence over docs patterns | |
| local code_patterns="feature|fix|bug|implement|refactor|add.*function|update.*code|create.*script|modify.*config|change.*logic|new.*api|endpoint|enhance" | |
| # Docs-only indicators (positive match) | |
| local docs_patterns="^readme|^changelog|^documentation|docs/|typo|spelling|comment only|license only|^update readme|^update changelog|^update docs" | |
| # Check for code patterns first (takes precedence) | |
| if echo "$task_lower" | grep -qE "$code_patterns"; then | |
| return 1 # Not docs-only | |
| fi | |
| # Check for docs patterns | |
| if echo "$task_lower" | grep -qE "$docs_patterns"; then | |
| return 0 # Is docs-only | |
| fi | |
| # Default: not docs-only (safer to create branch) | |
| return 1 | |
| } |
…tion helpers
- Add get_available_port() function to all three helpers
- Update start scripts to check port availability before starting
- Auto-select alternative port if default is in use
- Save actual port to /tmp/{tool}_port for status scripts
- Update status scripts to read actual port from saved file
- Document port management integration in overview.md
Integrates with PR #52 localhost port management for conflict avoidance.
…tion helpers
- Add get_available_port() function to all three helpers
- Update start scripts to check port availability before starting
- Auto-select alternative port if default is in use
- Save actual port to /tmp/{tool}_port for status scripts
- Update status scripts to read actual port from saved file
- Document port management integration in overview.md
Integrates with PR #52 localhost port management for conflict avoidance.
* feat: add AI orchestration frameworks (Langflow, CrewAI, AutoGen)
Add comprehensive integration for three major AI orchestration frameworks:
- Langflow: Visual drag-and-drop workflow builder (MIT, localhost:7860)
- CrewAI: Multi-agent teams with role-based orchestration (MIT, localhost:8501)
- AutoGen: Microsoft's agentic AI framework with MCP support (MIT, localhost:8081)
New files:
- .agent/tools/ai-orchestration/overview.md - Decision matrix and comparison
- .agent/tools/ai-orchestration/{langflow,crewai,autogen}.md - Setup guides
- .agent/tools/ai-orchestration/packaging.md - Deployment templates
- .agent/scripts/{langflow,crewai,autogen}-helper.sh - Setup scripts
- configs/{langflow,crewai,autogen}-config.json.txt - Config templates
Updated:
- .agent/AGENTS.md - Added ai-orchestration category
- README.md - Added AI Orchestration Frameworks section
- setup.sh - Added setup_ai_orchestration() function
All frameworks follow common design patterns aligned with existing Agno integration:
- Runtime directory: ~/.aidevops/{tool}/
- Virtual environment management
- Standard start/stop/status scripts
- Local LLM support via Ollama
* feat: integrate localhost-helper.sh port management into AI orchestration helpers
- Add get_available_port() function to all three helpers
- Update start scripts to check port availability before starting
- Auto-select alternative port if default is in use
- Save actual port to /tmp/{tool}_port for status scripts
- Update status scripts to read actual port from saved file
- Document port management integration in overview.md
Integrates with PR #52 localhost port management for conflict avoidance.



Summary
--loop-modeflag topre-edit-check.shfor autonomous branch decisions in loop agentslocalhost-helper.shfor conflict avoidanceChanges
Loop Mode Auto-Branch (
pre-edit-check.sh)Loop agents (
/full-loop,/ralph-loop) can now auto-decide branch handling:This eliminates the interactive prompt that previously stalled autonomous loops.
Port Management (
localhost-helper.sh)New commands:
check-port <port>- Check availability, suggest alternative if in usefind-port <start>- Find next available portlist-ports- Show common dev ports in usekill-port <port>- Kill process on portLocalhost Standards
Why
.localdomains + SSL + port checking:http://localhost:portStandard workflow:
Testing
Files Changed
pre-edit-check.sh--loop-modeflag with task detectionlocalhost-helper.shlocalhost.mdAGENTS.mdfull-loop.mdralph-loop.mdSummary by CodeRabbit
New Features
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.