Skip to content

fix: skip update check in headless/non-interactive sessions#2400

Merged
marcusquinn merged 1 commit intomainfrom
bugfix/headless-update-check-skip
Feb 26, 2026
Merged

fix: skip update check in headless/non-interactive sessions#2400
marcusquinn merged 1 commit intomainfrom
bugfix/headless-update-check-skip

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Feb 26, 2026

Summary

  • Adds is_headless() detection to aidevops-update-check.sh that skips the GitHub API network call (~300ms) when running in headless dispatch mode
  • Three detection signals: env vars (FULL_LOOP_HEADLESS, OPENCODE_HEADLESS, AIDEVOPS_HEADLESS), --headless flag, and no-TTY on stdin
  • --interactive flag overrides all headless detection for the greeting flow
  • Updated global config (~/.config/opencode/AGENTS.md) with explicit SKIP RULES, long-running task guidance, and ralph-loop routing

Problem

User feedback: "when I run a non-interactive opencode, it starts with aidevops update and that kills the whole point of the non-interactive part" and "the new system prompt is not letting it go through long running jobs"

Root Causes

  1. Update check in headless sessions: The script always made a network call to GitHub regardless of session type. In headless dispatch (opencode run), this added latency and sometimes blocked the session.
  2. Soft skip instruction: The global config said "skip this section for headless" but models often ignored it because the instruction was buried and not emphatic enough.
  3. Missing ralph-loop routing: No guidance for models to detect when a user wants long-running iterative work and route to /ralph-loop or /full-loop.

Changes

aidevops-update-check.sh

  • New is_headless() function with layered detection
  • Early return in main() that outputs version without network call
  • --interactive flag for explicit opt-in to full check

~/.config/opencode/AGENTS.md (global config, not in repo)

  • SKIP RULES section at top with hard gates for slash commands, headless mode, and direct task instructions
  • Long-Running Tasks section pointing to ralph-loop/full-loop with note that headless time budgets don't apply to interactive sessions
  • Update check call now passes --interactive flag

Testing

# Headless via env var — 10ms, no network
FULL_LOOP_HEADLESS=true bash aidevops-update-check.sh
# → aidevops v2.44.2 (headless - skipped update check)

# Headless via flag — 10ms, no network
bash aidevops-update-check.sh --headless
# → aidevops v2.44.2 (headless - skipped update check)

# Headless via no-TTY (piped) — 10ms, no network
echo "test" | bash aidevops-update-check.sh
# → aidevops v2.44.2 (headless - skipped update check)

# Interactive override — 300ms, full network check
bash aidevops-update-check.sh --interactive
# → UPDATE_AVAILABLE|2.44.2|2.133.12|OpenCode

# Interactive overrides env var
FULL_LOOP_HEADLESS=true bash aidevops-update-check.sh --interactive
# → UPDATE_AVAILABLE|2.44.2|2.133.12|OpenCode

ShellCheck: zero violations.

Summary by CodeRabbit

Release Notes

  • New Features
    • Added headless mode detection for non-interactive environments. When running in headless mode (via environment variables, CLI flag, or TTY absence), the update check is bypassed and a headless-specific status message is displayed instead.

Add is_headless() detection to aidevops-update-check.sh that skips the
network call to GitHub when running in headless dispatch mode. Detection
uses three signals: env vars (FULL_LOOP_HEADLESS, OPENCODE_HEADLESS,
AIDEVOPS_HEADLESS), --headless flag, and no-TTY on stdin.

The --interactive flag overrides all headless detection, used by the
AGENTS.md greeting flow when the model intentionally wants the full
update check.

Reduces headless session startup from ~300ms to ~10ms by eliminating
the curl to api.github.com.

Also updated ~/.config/opencode/AGENTS.md (global config, outside repo):
- Added explicit SKIP RULES section with hard gates for slash commands,
  headless mode, and direct task instructions
- Added Long-Running Tasks section pointing to ralph-loop for iterative
  development, with note that headless time budgets don't apply to
  interactive sessions
- Changed update check call to pass --interactive flag
@github-actions github-actions bot added the bug Auto-created from TODO.md tag label Feb 26, 2026
@gemini-code-assist
Copy link

Summary of Changes

Hello @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 addresses user feedback regarding slow non-interactive sessions and models ignoring skip rules by optimizing the aidevops-update-check.sh script. It introduces robust headless detection to prevent unnecessary network calls during automated runs and provides an explicit override for interactive scenarios. Additionally, it updates global configuration to better guide models on skipping checks and handling long-running tasks, significantly improving the efficiency and responsiveness of the system in various operational modes.

Highlights

  • Headless Session Detection: Implemented a new is_headless() function in aidevops-update-check.sh to detect non-interactive environments using environment variables, a --headless CLI flag, and TTY status.
  • Skipped Update Checks: The aidevops-update-check.sh script now performs an early return in its main() function when in headless mode, skipping the GitHub API network call and reducing latency.
  • Interactive Override: Added an --interactive flag that explicitly overrides all headless detection, allowing for a full update check even in otherwise non-interactive contexts.
  • Global Configuration Guidance: Updated the global config (~/.config/opencode/AGENTS.md) with explicit SKIP RULES, guidance for long-running tasks, and routing instructions for ralph-loop.
Changelog
  • .agents/scripts/aidevops-update-check.sh
    • Added a new is_headless() function to detect non-interactive sessions based on environment variables, CLI flags, and TTY status.
    • Implemented an early return in the main() function to skip network calls for update checks when in headless mode.
    • Introduced support for an --interactive flag to explicitly force a full update check, overriding headless detection.
Activity
  • No human activity has occurred on this pull request yet.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0eaa61b and 79a5921.

📒 Files selected for processing (1)
  • .agents/scripts/aidevops-update-check.sh

Walkthrough

A new is_headless() helper function was added to detect non-interactive execution via environment variables (FULL_LOOP_HEADLESS, OPENCODE_HEADLESS, AIDEVOPS_HEADLESS), CLI flag --headless, and TTY absence, with --interactive override. When headless, update checks are bypassed and a version message is output before exit.

Changes

Cohort / File(s) Summary
Headless Detection Enhancement
.agents/scripts/aidevops-update-check.sh
Added is_headless() function to detect non-interactive execution via multiple signals (env vars, CLI flags, TTY state). Integrated into main flow with early exit for headless runs; existing update-check logic preserved for interactive mode.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

Headless or interactive—now the script knows best,
Environment whispers, and TTY's the test,
With flags held aloft and logic precise,
Updates can wait when automation's the vice! 🤖✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introducing headless/non-interactive session detection to skip the update check network call.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bugfix/headless-update-check-skip

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 88 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Thu Feb 26 21:20:00 UTC 2026: Code review monitoring started
Thu Feb 26 21:20:00 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 88

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 88
  • VULNERABILITIES: 0

Generated on: Thu Feb 26 21:20:03 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a check to skip the update process in headless or non-interactive sessions, which is a valuable optimization. The implementation is sound, but I've suggested a refactoring for the new is_headless function to improve its efficiency and readability by simplifying argument parsing and consolidating conditional logic, aligning with best practices for robust CLI argument parsing and loop efficiency.

Comment on lines +130 to +163
is_headless() {
# Detect non-interactive/headless mode from multiple signals.
# The --interactive flag overrides all headless detection (used by
# AGENTS.md greeting flow when the model intentionally wants the
# full update check despite running inside a Bash tool with no TTY).
local arg
for arg in "$@"; do
if [[ "$arg" == "--interactive" ]]; then
return 1
fi
done
# 1. Explicit env vars set by dispatch systems
if [[ "${FULL_LOOP_HEADLESS:-}" == "true" ]]; then
return 0
fi
if [[ "${OPENCODE_HEADLESS:-}" == "true" ]]; then
return 0
fi
if [[ "${AIDEVOPS_HEADLESS:-}" == "true" ]]; then
return 0
fi
# 2. CLI flag: --headless passed to this script
for arg in "$@"; do
if [[ "$arg" == "--headless" ]]; then
return 0
fi
done
# 3. No TTY on stdin (piped input, e.g. opencode run / claude -p)
# This catches cases where the model ignores AGENTS.md skip rules.
if [[ ! -t 0 ]]; then
return 0
fi
return 1
}

Choose a reason for hiding this comment

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

medium

The is_headless function can be made more efficient and readable. It currently iterates over the script's arguments twice to check for --interactive and --headless flags. This can be done in a single pass, improving loop efficiency and aligning with best practices for robust CLI argument parsing. Additionally, the multiple if statements for checking environment variables can be consolidated into one for conciseness.

is_headless() {
	# Detect non-interactive/headless mode from multiple signals.
	# The --interactive flag overrides all headless detection (used by
	# AGENTS.md greeting flow when the model intentionally wants the
	# full update check despite running inside a Bash tool with no TTY).
	local interactive=false
	local headless=false
	local arg
	for arg in "$@" ; do
		case "$arg" in
			--interactive) interactive=true ;;
			--headless) headless=true ;;
		esac
	done

	if [[ "$interactive" == "true" ]]; then
		return 1
	}

	# 1. Explicit env vars set by dispatch systems
	if [[ "${FULL_LOOP_HEADLESS:-}" == "true" || "${OPENCODE_HEADLESS:-}" == "true" || "${AIDEVOPS_HEADLESS:-}" == "true" ]]; then
		return 0
	}

	# 2. CLI flag
	if [[ "$headless" == "true" ]]; then
		return 0
	}

	# 3. No TTY on stdin (piped input, e.g. opencode run / claude -p)
	#    This catches cases where the model ignores AGENTS.md skip rules.
	if [[ ! -t 0 ]]; then
		return 0
	}

	return 1
}
References
  1. When parsing CLI command strings to extract specific arguments, use a robust method that accounts for different flag formats (e.g., '--flag value', '--flag=value', and valueless flags) by maintaining a whitelist of flags known to consume an additional argument. This rule emphasizes using robust methods for parsing CLI arguments, which includes efficient single-pass processing of flags like --interactive and --headless.
  2. In shell scripts, move the calculation of loop-invariant variables outside of loops to improve efficiency. This rule promotes improving loop efficiency by avoiding redundant iterations, such as processing the same argument list multiple times when a single pass suffices.

@marcusquinn marcusquinn merged commit 735e8f4 into main Feb 26, 2026
25 checks passed
@marcusquinn marcusquinn deleted the bugfix/headless-update-check-skip branch March 3, 2026 03:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Auto-created from TODO.md tag

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant