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
18 changes: 10 additions & 8 deletions .agents/scripts/commands/pulse.md
Original file line number Diff line number Diff line change
Expand Up @@ -558,23 +558,25 @@ sleep 2

If a dispatch attempt exits immediately with provider/auth failure (for example `Token refresh failed`, `authentication`, `401`, `403`, `400` in startup logs), do not wait for next cycle. Re-dispatch in the same cycle via `headless-runtime-helper.sh run` with an explicit alternate model/provider and continue filling remaining slots.

**Launch validation is mandatory (t1452):** after each dispatch, verify the worker actually started and did not fall through to CLI usage output.
**Launch validation is mandatory (t1452/t1453):** after each dispatch, validate the launch with the wrapper helper. This keeps the gate deterministic and aligned with wrapper-side enforcement.

```bash
# 1) Process exists (session-key must map to a live run)
pgrep -fal "issue-<number>|Issue #<number>:" >/dev/null
# Source wrapper helper once per pulse run (safe when sourced)
source ~/.aidevops/agents/scripts/pulse-wrapper.sh

# 2) Startup log is not CLI help/usage output
LOG_PATH="/tmp/pulse-<slug>-<number>.log"
if [[ -f "$LOG_PATH" ]] && rg -q '^opencode run \[message\.\.]|^run opencode with a message|^Options:' "$LOG_PATH"; then
echo "Invalid worker launch for #<number> (CLI usage output)"
# check_worker_launch returns 0 only when the worker process appears
# and no CLI usage-output markers are detected in known startup logs.
if ! check_worker_launch <number> <slug>; then
echo "Invalid worker launch for #<number>"
# Relaunch immediately via helper (never leave this for next pulse)
fi
```

If validation fails, re-dispatch immediately via `headless-runtime-helper.sh run`, add a short issue comment noting the failed launch and correction, and continue filling slots.

9. **Fill-to-cap post-condition (t1449):** before ending the pulse cycle, compare active workers vs `MAX_WORKERS`. If below cap and runnable scoped issues/PR work exists in any repo class, continue dispatching until cap is reached or no runnable candidates remain. Do not leave slots idle because of class reservations when one class is PR-capped or empty.
9. **Fill-to-cap post-condition (t1449/t1453):** before ending the pulse cycle, compare active workers vs `MAX_WORKERS`. If below cap and runnable scoped issues/PR work exists in any repo class, continue dispatching until cap is reached or no runnable candidates remain. Do not leave slots idle because of class reservations when one class is PR-capped or empty.

`pulse-wrapper.sh` now enforces this invariant after the LLM pulse pass via bounded backfill cycles (until max workers or no runnable work) and treats queued issues without live workers as launch-validation failures to backfill immediately.

### Candidate discovery baseline (t1443 + t1448)

Expand Down
211 changes: 211 additions & 0 deletions .agents/scripts/pulse-wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@
DAILY_PR_CAP="${DAILY_PR_CAP:-5}" # Max PRs created per repo per day (GH#3821)
PRODUCT_RESERVATION_PCT="${PRODUCT_RESERVATION_PCT:-60}" # % of worker slots reserved for product repos (t1423)
QUALITY_DEBT_CAP_PCT="${QUALITY_DEBT_CAP_PCT:-$(config_get "orchestration.quality_debt_cap_pct" "30")}" # % cap for quality-debt dispatch share
PULSE_BACKFILL_MAX_ATTEMPTS="${PULSE_BACKFILL_MAX_ATTEMPTS:-3}" # Additional pulse passes when below utilization target (t1453)
PULSE_LAUNCH_GRACE_SECONDS="${PULSE_LAUNCH_GRACE_SECONDS:-20}" # Grace window for worker process to appear after dispatch (t1453)

# Process guard limits (t1398)
CHILD_RSS_LIMIT_KB="${CHILD_RSS_LIMIT_KB:-2097152}" # 2 GB default — kill child if RSS exceeds this
Expand All @@ -106,6 +108,8 @@
if [[ "$QUALITY_DEBT_CAP_PCT" -gt 100 ]]; then
QUALITY_DEBT_CAP_PCT=100
fi
PULSE_BACKFILL_MAX_ATTEMPTS=$(_validate_int PULSE_BACKFILL_MAX_ATTEMPTS "$PULSE_BACKFILL_MAX_ATTEMPTS" 3 0)
PULSE_LAUNCH_GRACE_SECONDS=$(_validate_int PULSE_LAUNCH_GRACE_SECONDS "$PULSE_LAUNCH_GRACE_SECONDS" 20 5)
CHILD_RSS_LIMIT_KB=$(_validate_int CHILD_RSS_LIMIT_KB "$CHILD_RSS_LIMIT_KB" 2097152 1)
CHILD_RUNTIME_LIMIT=$(_validate_int CHILD_RUNTIME_LIMIT "$CHILD_RUNTIME_LIMIT" 1800 1)
SHELLCHECK_RSS_LIMIT_KB=$(_validate_int SHELLCHECK_RSS_LIMIT_KB "$SHELLCHECK_RSS_LIMIT_KB" 1048576 1)
Expand Down Expand Up @@ -1668,6 +1672,212 @@
return 0
}

#######################################
# Count active worker processes
# Returns: count via stdout
#######################################
count_active_workers() {
local count
count=$(ps axo command | grep '[/]full-loop' | grep -c '[.]opencode') || count=0
echo "$count"
return 0
}

#######################################
# Get current max workers from pulse-max-workers file
# Returns: numeric value via stdout (defaults to 1)
#######################################
get_max_workers_target() {
local max_workers_file="${HOME}/.aidevops/logs/pulse-max-workers"
local max_workers
max_workers=$(cat "$max_workers_file" 2>/dev/null || echo "1")
[[ "$max_workers" =~ ^[0-9]+$ ]] || max_workers=1
if [[ "$max_workers" -lt 1 ]]; then
max_workers=1
fi
echo "$max_workers"
return 0
}

#######################################
# Count runnable backlog candidates across pulse scope
# Heuristic for t1453 utilization loop:
# - open unassigned, non-blocked issues
# - open PRs with failing checks or changes requested
# Returns: count via stdout
#######################################
count_runnable_candidates() {
local repos_json="${REPOS_JSON}"
if [[ ! -f "$repos_json" ]] || ! command -v jq &>/dev/null; then
echo "0"
return 0
fi

local total=0
while IFS='|' read -r slug _path; do
[[ -n "$slug" ]] || continue

local issue_json
issue_json=$(gh issue list --repo "$slug" --state open --json assignees,labels --limit 100 2>/dev/null) || issue_json="[]"
local issue_count
issue_count=$(echo "$issue_json" | jq '[.[] | select((.assignees | length) == 0 and (.labels | map(.name) | index("status:blocked") | not))] | length' 2>/dev/null) || issue_count=0
[[ "$issue_count" =~ ^[0-9]+$ ]] || issue_count=0

local pr_json
pr_json=$(gh pr list --repo "$slug" --state open --json reviewDecision,statusCheckRollup --limit 100 2>/dev/null) || pr_json="[]"
Comment on lines +1721 to +1727

Choose a reason for hiding this comment

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

medium

The gh CLI commands are limited to fetching 100 items by default. If a repository has more than 100 open issues or pull requests, this count of runnable candidates will be incomplete, potentially causing the backfill loop to terminate prematurely even when there is more work available. To ensure all items are retrieved, use the --paginate flag.

Suggested change
issue_json=$(gh issue list --repo "$slug" --state open --json assignees,labels --limit 100 2>/dev/null) || issue_json="[]"
local issue_count
issue_count=$(echo "$issue_json" | jq '[.[] | select((.assignees | length) == 0 and (.labels | map(.name) | index("status:blocked") | not))] | length' 2>/dev/null) || issue_count=0
[[ "$issue_count" =~ ^[0-9]+$ ]] || issue_count=0
local pr_json
pr_json=$(gh pr list --repo "$slug" --state open --json reviewDecision,statusCheckRollup --limit 100 2>/dev/null) || pr_json="[]"
issue_json=$(gh issue list --repo "$slug" --state open --json assignees,labels --paginate 2>/dev/null) || issue_json="[]"
local issue_count
issue_count=$(echo "$issue_json" | jq '[.[] | select((.assignees | length) == 0 and (.labels | map(.name) | index("status:blocked") | not))] | length' 2>/dev/null) || issue_count=0
[[ "$issue_count" =~ ^[0-9]+$ ]] || issue_count=0
local pr_json
pr_json=$(gh pr list --repo "$slug" --state open --json reviewDecision,statusCheckRollup --paginate 2>/dev/null) || pr_json="[]"
References
  1. When fetching a list of items from the GitHub API with the gh command, use the --paginate flag to ensure all items are retrieved, not just the first page.

local pr_count
pr_count=$(echo "$pr_json" | jq '[.[] | select(.reviewDecision == "CHANGES_REQUESTED" or ((.statusCheckRollup // []) | any((.conclusion // .state) == "FAILURE")))] | length' 2>/dev/null) || pr_count=0
[[ "$pr_count" =~ ^[0-9]+$ ]] || pr_count=0

total=$((total + issue_count + pr_count))
done < <(jq -r '.initialized_repos[] | select(.pulse == true and (.local_only // false) == false and .slug != "") | "\(.slug)|\(.path)"' "$repos_json" 2>/dev/null)

echo "$total"
return 0
}

#######################################
# Count queued issues that do not have an active worker process
# This is a launch-validation signal: queued labels imply dispatch,
# but no matching worker indicates startup failure or immediate exit.
# Returns: count via stdout
#######################################
count_queued_without_worker() {
local repos_json="${REPOS_JSON}"
if [[ ! -f "$repos_json" ]] || ! command -v jq &>/dev/null; then
echo "0"
return 0
fi

local total=0
while IFS= read -r slug; do
[[ -n "$slug" ]] || continue
local queued_numbers
queued_numbers=$(gh issue list --repo "$slug" --state open --label "status:queued" --json number --jq '.[].number' --limit 100 2>/dev/null) || queued_numbers=""

Choose a reason for hiding this comment

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

medium

The gh issue list command is limited to fetching 100 items by default. If a repository has more than 100 issues with the status:queued label, this function will not count all of them, leading to an inaccurate queued_without_worker count. This could prevent the backfill logic from triggering correctly for failed worker launches. To ensure all queued issues are checked, use the --paginate flag.

Suggested change
queued_numbers=$(gh issue list --repo "$slug" --state open --label "status:queued" --json number --jq '.[].number' --limit 100 2>/dev/null) || queued_numbers=""
queued_numbers=$(gh issue list --repo "$slug" --state open --label "status:queued" --json number --jq '.[].number' --paginate 2>/dev/null) || queued_numbers=""
References
  1. When fetching a list of items from the GitHub API with the gh command, use the --paginate flag to ensure all items are retrieved, not just the first page.

if [[ -z "$queued_numbers" ]]; then
continue
fi

while IFS= read -r issue_num; do
[[ "$issue_num" =~ ^[0-9]+$ ]] || continue
if ! pgrep -fal "issue-${issue_num}|Issue #${issue_num}:" >/dev/null; then
total=$((total + 1))
fi
Comment on lines +1761 to +1765
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

pgrep -fal has portability issues between Linux and macOS.

The -a flag has different meanings:

  • Linux (GNU pgrep): -a, --list-full — shows full command line
  • macOS (BSD pgrep): -a — include process ancestors in match

Since output is discarded to /dev/null, only the exit code matters. The -l flag is also unnecessary here. For cross-platform reliability, use just -f:

🔧 Proposed fix for portability
 		while IFS= read -r issue_num; do
 			[[ "$issue_num" =~ ^[0-9]+$ ]] || continue
-			if ! pgrep -fal "issue-${issue_num}|Issue #${issue_num}:" >/dev/null; then
+			if ! pgrep -f "issue-${issue_num}|Issue #${issue_num}:" >/dev/null 2>&1; then
 				total=$((total + 1))
 			fi
 		done <<<"$queued_numbers"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/scripts/pulse-wrapper.sh around lines 1761 - 1765, The pgrep
invocation in the while loop (inside pulse-wrapper.sh where issue_num is read
and total is incremented) uses `pgrep -fal`, which is not portable between Linux
and macOS; replace the call with a portable check using only `pgrep -f
"issue-${issue_num}|Issue #${issue_num}:"` (remove `-a` and `-l`) so the script
relies solely on the exit status to decide whether to increment `total`,
ensuring `issue_num`, the pgrep check, and the total increment logic remain
unchanged.

done <<<"$queued_numbers"
done < <(jq -r '.initialized_repos[] | select(.pulse == true and (.local_only // false) == false and .slug != "") | .slug' "$repos_json" 2>/dev/null)

echo "$total"
return 0
}

#######################################
# Launch validation gate for pulse dispatches (t1453)
#
# Arguments:
# $1 - issue number
# $2 - repo slug (owner/repo)
# $3 - optional grace timeout in seconds
#
# Exit codes:
# 0 - worker launch appears valid (process observed, no CLI usage output marker)
# 1 - launch invalid (no process within grace window or usage output detected)
#######################################
check_worker_launch() {
local issue_number="$1"
local repo_slug="$2"
local grace_seconds="${3:-$PULSE_LAUNCH_GRACE_SECONDS}"

if [[ ! "$issue_number" =~ ^[0-9]+$ ]] || [[ -z "$repo_slug" ]]; then
echo "[pulse-wrapper] check_worker_launch: invalid arguments issue='$issue_number' repo='$repo_slug'" >>"$LOGFILE"
return 1
fi
[[ "$grace_seconds" =~ ^[0-9]+$ ]] || grace_seconds="$PULSE_LAUNCH_GRACE_SECONDS"
if [[ "$grace_seconds" -lt 1 ]]; then
grace_seconds=1
fi

local safe_slug
safe_slug=$(echo "$repo_slug" | tr '/:' '--')
local -a log_candidates=(
"/tmp/pulse-${safe_slug}-${issue_number}.log"
"/tmp/pulse-${issue_number}.log"
)

local elapsed=0
local poll_seconds=2
while [[ "$elapsed" -lt "$grace_seconds" ]]; do
if pgrep -fal "issue-${issue_number}|Issue #${issue_number}:" >/dev/null; then
local candidate
for candidate in "${log_candidates[@]}"; do
if [[ -f "$candidate" ]] && rg -q '^opencode run \[message\.\.\]|^run opencode with a message|^Options:' "$candidate"; then
echo "[pulse-wrapper] Launch validation failed for issue #${issue_number} (${repo_slug}) — CLI usage output detected in ${candidate}" >>"$LOGFILE"
return 1
fi
done
return 0
Comment on lines +1809 to +1817
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify if ripgrep (rg) is used elsewhere in the codebase or if there's a documented dependency

# Check for rg usage in shell scripts
echo "=== rg usage in .agents/scripts/ ==="
rg -l '\brg\b' .agents/scripts/*.sh 2>/dev/null || echo "No other rg usage found"

# Check if there's a dependency list
echo ""
echo "=== Checking for documented dependencies ==="
fd -t f -e md 'INSTALL|SETUP|DEPENDENCY|README' . --exec head -50 {} 2>/dev/null | grep -i 'ripgrep\|rg' || echo "No ripgrep dependency documented"

Repository: marcusquinn/aidevops

Length of output: 3487


🏁 Script executed:

#!/bin/bash

# 1. Check for ripgrep in dependency/setup files
echo "=== Ripgrep in dependency/setup files ==="
fd -t f \( -name 'setup.sh' -o -name '.tool-versions' -o -name 'Brewfile' -o -name 'requirements*.txt' -o -name 'package.json' -o -name 'Dockerfile' \) . --exec grep -l 'ripgrep\|rg' {} \; 2>/dev/null || echo "No explicit ripgrep in common dependency files found"

# 2. Check if README or INSTALL documents ripgrep as requirement
echo ""
echo "=== README/INSTALL mentioning ripgrep ==="
fd -t f \( -name 'README*' -o -name 'INSTALL*' -o -name 'SETUP*' \) . --exec grep -i 'ripgrep\|rg' {} + 2>/dev/null || echo "Not found in README/INSTALL"

# 3. Check pgrep usage pattern in .agents/scripts/
echo ""
echo "=== pgrep usage in .agents/scripts/ ==="
rg -n 'pgrep' .agents/scripts/*.sh | head -20

# 4. Read the actual lines 1809-1817 in pulse-wrapper.sh
echo ""
echo "=== Lines 1809-1817 in pulse-wrapper.sh ==="
sed -n '1809,1817p' .agents/scripts/pulse-wrapper.sh

Repository: marcusquinn/aidevops

Length of output: 2840


🏁 Script executed:

#!/bin/bash

# 1. Check for pgrep -fal specifically
echo "=== pgrep -fal usage in codebase ==="
rg 'pgrep.*-.*a.*l' .agents/scripts/*.sh

# 2. Check for any tools documentation
echo ""
echo "=== Tool requirements documentation ==="
cat .tool-versions 2>/dev/null || echo "No .tool-versions found"
echo ""
cat .github/workflows/*.yml 2>/dev/null | grep -A5 'ripgrep\|setup-' | head -20 || echo "No tool setup in workflows"

# 3. Check if there's any comment about tool dependencies in the scripts themselves
echo ""
echo "=== Tool requirement comments in pulse-wrapper.sh ==="
head -50 .agents/scripts/pulse-wrapper.sh | grep -i 'require\|depend\|need\|install'

# 4. Check what the -a and -l flags do (look at pgrep man page context or comments)
echo ""
echo "=== Context around pgrep usage in pulse-wrapper.sh ==="
sed -n '1800,1825p' .agents/scripts/pulse-wrapper.sh

Repository: marcusquinn/aidevops

Length of output: 3538


Remove non-portable pgrep flags and document or replace rg dependency.

Line 1809 uses pgrep -fal, where -a and -l are GNU/Linux-only extensions not available on macOS. Replace with POSIX-compatible pgrep -f.

Additionally, rg (ripgrep) is used here without any documented setup requirement. While ripgrep is a project pattern, the absence of any dependency documentation creates maintenance friction. Either add ripgrep to an explicit setup/dependency file, or use grep -E as a portable fallback.

Suggested fixes
 	while [[ "$elapsed" -lt "$grace_seconds" ]]; do
-		if pgrep -fal "issue-${issue_number}|Issue #${issue_number}:" >/dev/null; then
+		if pgrep -f "issue-${issue_number}|Issue #${issue_number}:" >/dev/null 2>&1; then
 			local candidate
 			for candidate in "${log_candidates[@]}"; do
-				if [[ -f "$candidate" ]] && rg -q '^opencode run \[message\.\.\]|^run opencode with a message|^Options:' "$candidate"; then
+				if [[ -f "$candidate" ]] && grep -Eq '^opencode run \[message\.\.\]|^run opencode with a message|^Options:' "$candidate"; then
 					echo "[pulse-wrapper] Launch validation failed for issue #${issue_number} (${repo_slug}) — CLI usage output detected in ${candidate}" >>"$LOGFILE"
 					return 1
 				fi

Note: pgrep -fal appears in at least one other location in pulse-wrapper.sh; same fix applies.

📝 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
if pgrep -fal "issue-${issue_number}|Issue #${issue_number}:" >/dev/null; then
local candidate
for candidate in "${log_candidates[@]}"; do
if [[ -f "$candidate" ]] && rg -q '^opencode run \[message\.\.\]|^run opencode with a message|^Options:' "$candidate"; then
echo "[pulse-wrapper] Launch validation failed for issue #${issue_number} (${repo_slug}) — CLI usage output detected in ${candidate}" >>"$LOGFILE"
return 1
fi
done
return 0
if pgrep -f "issue-${issue_number}|Issue #${issue_number}:" >/dev/null 2>&1; then
local candidate
for candidate in "${log_candidates[@]}"; do
if [[ -f "$candidate" ]] && grep -Eq '^opencode run \[message\.\.\]|^run opencode with a message|^Options:' "$candidate"; then
echo "[pulse-wrapper] Launch validation failed for issue #${issue_number} (${repo_slug}) — CLI usage output detected in ${candidate}" >>"$LOGFILE"
return 1
fi
done
return 0
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/scripts/pulse-wrapper.sh around lines 1809 - 1817, The pgrep
invocation using non-portable flags in the condition around issue handling (the
pgrep -fal "issue-${issue_number}|Issue #${issue_number}:") should be changed to
the POSIX-compatible form (use pgrep -f) and any logic that relied on -l/-a
output adjusted accordingly; also address the ripgrep (rg) dependency used in
the loop that checks files (rg -q '...') by either documenting rg in project
setup/dependencies or replacing rg with a portable grep -E/grep -q equivalent,
and apply the same pgrep fix to other occurrences of pgrep -fal in
pulse-wrapper.sh so behavior remains consistent.

fi
sleep "$poll_seconds"
elapsed=$((elapsed + poll_seconds))
done

echo "[pulse-wrapper] Launch validation failed for issue #${issue_number} (${repo_slug}) — no active worker process within ${grace_seconds}s" >>"$LOGFILE"
return 1
}

#######################################
# Enforce utilization invariants post-pulse (t1453)
#
# Invariant: keep dispatching pulse cycles until either:
# - active workers >= MAX_WORKERS, OR
# - no runnable work remains in scope
#
# Launch validation integration:
# queued issues with no active worker are treated as launch failures,
# which trigger an immediate backfill cycle.
#######################################
enforce_utilization_invariants() {
local attempts=0
local max_attempts="$PULSE_BACKFILL_MAX_ATTEMPTS"

while [[ "$attempts" -lt "$max_attempts" ]]; do
if [[ -f "$STOP_FLAG" ]]; then
echo "[pulse-wrapper] Stop flag present during utilization enforcement — exiting" >>"$LOGFILE"
return 0
fi

local max_workers active_workers runnable_count queued_without_worker
max_workers=$(get_max_workers_target)
active_workers=$(count_active_workers)
runnable_count=$(count_runnable_candidates)
queued_without_worker=$(count_queued_without_worker)

[[ "$max_workers" =~ ^[0-9]+$ ]] || max_workers=1
[[ "$active_workers" =~ ^[0-9]+$ ]] || active_workers=0
[[ "$runnable_count" =~ ^[0-9]+$ ]] || runnable_count=0
[[ "$queued_without_worker" =~ ^[0-9]+$ ]] || queued_without_worker=0

if [[ "$active_workers" -ge "$max_workers" && "$queued_without_worker" -eq 0 ]]; then
echo "[pulse-wrapper] Utilization invariant satisfied: active workers ${active_workers}/${max_workers}" >>"$LOGFILE"
return 0
fi

if [[ "$runnable_count" -eq 0 && "$queued_without_worker" -eq 0 ]]; then
echo "[pulse-wrapper] Utilization invariant satisfied: no runnable work remains (active ${active_workers}/${max_workers})" >>"$LOGFILE"
return 0
fi

attempts=$((attempts + 1))
echo "[pulse-wrapper] Backfill attempt ${attempts}/${max_attempts}: active=${active_workers}/${max_workers}, runnable=${runnable_count}, queued_without_worker=${queued_without_worker}" >>"$LOGFILE"

# Refresh prompt state before each backfill cycle so pulse sees latest context.
prefetch_state || true
run_pulse
done

echo "[pulse-wrapper] Reached backfill attempt cap (${max_attempts}) before utilization invariant converged" >>"$LOGFILE"
return 0
}

#######################################
# Main
#
Expand Down Expand Up @@ -1719,6 +1929,7 @@
fi

run_pulse
enforce_utilization_invariants
return 0
}

Expand Down Expand Up @@ -1787,7 +1998,7 @@
local mb=$((rss / 1024))
killed=$((killed + 1))
total_mb=$((total_mb + mb))
done < <(ps axo pid,tty,etime,rss,command | grep 'node.*opencode' | grep -v '[.]opencode')

Check warning on line 2001 in .agents/scripts/pulse-wrapper.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define a constant instead of using the literal '[.]opencode' 4 times.

See more on https://sonarcloud.io/project/issues?id=marcusquinn_aidevops&issues=AZzfwJ2SFNwvfi1UG3xr&open=AZzfwJ2SFNwvfi1UG3xr&pullRequest=4198

if [[ "$killed" -gt 0 ]]; then
echo "[pulse-wrapper] Cleaned up $killed orphaned opencode processes (freed ~${total_mb}MB)" >>"$LOGFILE"
Expand Down
Loading