t1426: Upstream watch — track external repos for release monitoring#4003
t1426: Upstream watch — track external repos for release monitoring#4003marcusquinn merged 12 commits intomainfrom
Conversation
…backlog [skip ci]
…1424) Add upstream-watch-helper.sh to maintain a watchlist of external repos we've borrowed ideas/code from. Checks for new releases, shows changelog diffs between last-seen version and latest, supports explicit ack flow. Distinct from skill-sources.json (imported skills) and contribution-watch (repos we've contributed to) — this covers 'inspiration repos' for passive monitoring. Components: - upstream-watch-helper.sh: add/remove/check/ack/status commands - configs/upstream-watch.json: watchlist config (committed template) - cache/upstream-watch-state.json: runtime state (gitignored) - Auto-update integration: 24h-gated check in auto-update-helper.sh - Docs: AGENTS.md capabilities + domain index, services.md, settings.md First watched repo: vercel-labs/portless (local dev hosting comparison). Closes #TBD
- Only advance 24h gate on successful check (auto-update-helper.sh) - Use AIDEVOPS_AGENTS_DIR instead of hardcoded path (auto-update-helper.sh) - Don't advance last_commit_seen on check — only on ack (upstream-watch-helper.sh) - Capture gh api and jq errors instead of suppressing with 2>/dev/null - Add schema example to upstream-watch.json comment - Align t1424 TODO description with shipped scope
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds an "Upstream watch" capability: a new CLI (upstream-watch-helper.sh) to track external GitHub repos for releases/commits, a committed config template and state handling, and integration into the auto-update flow with a configurable 24h gate plus documentation and feature toggles. Changes
Sequence Diagram(s)sequenceDiagram
participant AutoUpdate as Auto-Update\n(.agents/scripts/auto-update-helper.sh)
participant UpWatch as UpstreamWatch\n(.agents/scripts/upstream-watch-helper.sh)
participant Config as Config\n(.agents/configs/upstream-watch.json)
participant State as State\n(~/.aidevops/cache/upstream-watch-state.json)
participant GH as GitHub API\n(via gh CLI)
AutoUpdate->>State: read last_upstream_watch_check
AutoUpdate->>AutoUpdate: compute elapsed time vs configured hours
alt elapsed >= interval
AutoUpdate->>UpWatch: run `check` command
UpWatch->>Config: load watchlist
loop per watched repo
UpWatch->>GH: fetch latest release
UpWatch->>GH: fetch latest commit on default branch
UpWatch->>State: compare last_seen vs fetched
alt new release or commit
UpWatch->>UpWatch: generate diff / mark updates_pending
end
UpWatch->>State: update last_checked (not last_seen until ack)
end
UpWatch-->>AutoUpdate: return status/results
AutoUpdate->>State: update last_upstream_watch_check
else within interval
AutoUpdate->>AutoUpdate: skip upstream check (log)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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, 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 introduces a robust 'Upstream Watch' capability, allowing the system to automatically track and report on updates from external GitHub repositories. This feature is designed to keep developers informed about new releases and significant changes in projects that serve as inspiration or reference, without requiring direct code integration. It streamlines the process of monitoring external dependencies and ideas, ensuring that relevant advancements are noted and reviewed efficiently. Highlights
Changelog
Activity
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: Mon Mar 9 20:16:45 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
There was a problem hiding this comment.
Code Review
This pull request introduces a valuable upstream-watch-helper.sh script for monitoring external repositories, and integrates it well into the existing auto-update-helper.sh. The new script is robust, with good error handling and state management. I've provided a couple of suggestions to enhance its reliability and maintainability. One comment addresses a potential bug in release checking that could miss updates, and the other aims to improve debuggability in the auto-update script by referencing established repository rules. Overall, this is a solid and well-executed feature addition.
|
Dispatching worker to address unresolved review bot suggestions.
|
- Use --paginate for gh api releases to avoid missing releases when repos have >20 releases since last check (upstream-watch-helper.sh) - Remove 2>/dev/null from is_feature_enabled call to surface jq parse errors from malformed settings files (auto-update-helper.sh)
🔍 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: Mon Mar 9 20:52:01 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.agents/AGENTS.md:
- Line 237: Update the "Auto-update" line in AGENTS.md to precisely reflect what
auto-update-helper.sh handles: mention that auto-update covers
skill/OpenClaw/tool freshness and upstream watch checks (via
auto-update-helper.sh), and remove or clarify the claim that repo sync is
included—instead state that repo sync is performed separately by the aidevops
repo-sync scheduler; keep AGENTS.md as the single source of truth for these
operational details.
In @.agents/scripts/auto-update-helper.sh:
- Around line 38-39: The feature-toggle mapping is missing entries for
upstream_watch/upstream_watch_hours causing env overrides to be ignored; update
the _ft_env_map() function to add cases for "upstream_watch" and
"upstream_watch_hours" that echo "AIDEVOPS_UPSTREAM_WATCH" and
"AIDEVOPS_UPSTREAM_WATCH_HOURS" respectively, and add "upstream_watch" and
"upstream_watch_hours" to the toggle_keys list in _load_feature_toggles_legacy()
so is_feature_enabled and get_feature_toggle (used around lines 872 and 878) can
pick up environment overrides as documented.
In @.agents/scripts/upstream-watch-helper.sh:
- Around line 367-380: The script currently may treat partial GitHub API
failures as success; ensure any probe failure sets the shared flag probe_failed
(e.g., in the block handling gh api for releases where you already set
probe_failed=true) for all error branches referencing release_json, issues, or
tags (the other failure blocks around the comments you noted at 399-408 and
421-476), and add a final check in the main probe routine to exit with a
non-zero status (exit 1 or 2) if probe_failed is true so the caller
(.agents/scripts/auto-update-helper.sh) can detect and retry; use the existing
_log_warn for messages and preserve release_json/api_stderr handling but make
probe_failed authoritative for failure exit.
- Around line 442-459: The script only marks .repos[$slug].updates_pending based
on has_new_release, so commit-only changes (has_new_commits) aren't recorded
when --verbose is false; update the jq pending logic in the state update (the
command that sets state via jq --argjson pending ...) to set pending when either
has_new_release or has_new_commits is true (i.e. pending = (has_new_release ||
has_new_commits)); also consider incrementing updates_found when has_new_commits
is true even if verbose is false so dashboards/counting reflect commit-only
updates (refer to variables has_new_commits, has_new_release, updates_found,
verbose, state, now, slug).
- Line 489: Replace the pipeline echo "$body" | head -20 | sed 's/^/ /' with
a single sed invocation using a here-string to avoid pipes/SIGPIPE: use sed -n
'1,20{s/^/ /;p}' <<< "$body" so sed both limits to the first 20 lines and
prefixes each line with four spaces in one command.
In `@TODO.md`:
- Line 111: Update the TODO entry to use the actual config path used by the
implementation: replace the string "configs/upstream-watch.json" with
".agents/configs/upstream-watch.json" in the t1426 description so the config
location matches the real implementation (leave the rest of the entry, including
state path "~/.aidevops/cache/upstream-watch-state.json" and other metadata,
unchanged).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e1ea4519-c4fe-409a-ae8a-98d2af9bc241
📒 Files selected for processing (8)
.agents/AGENTS.md.agents/configs/upstream-watch.json.agents/reference/services.md.agents/reference/settings.md.agents/scripts/auto-update-helper.sh.agents/scripts/upstream-watch-helper.sh.task-counterTODO.md
|
Pulse triage: PR has CHANGES_REQUESTED from CodeRabbit. All 8 worker slots are currently filled. This PR is queued for the next available slot to address review feedback. |
|
Dispatching worker to address 3 unresolved review suggestions.
|
- AGENTS.md: clarify auto-update scope (skill/upstream/OpenClaw/tool freshness only; repo sync runs separately via aidevops repo-sync scheduler) - shared-constants.sh: add upstream_watch and upstream_watch_hours to _ft_env_map() and toggle_keys so env var overrides work as documented - upstream-watch-helper.sh: propagate probe failures to prevent global last_check advancement on partial GitHub API errors (return 1) - upstream-watch-helper.sh: track commit-only changes as updates_pending and show summary even without --verbose - upstream-watch-helper.sh: replace echo|head|sed pipelines with sed -n here-strings to eliminate unnecessary pipes - AGENTS.md + TODO.md: fix config path from configs/ to .agents/configs/
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.agents/scripts/shared-constants.sh:
- Line 1483: The legacy env override list defined in the toggle_keys local
variable is missing max_interactive_sessions (which _ft_env_map maps to
AIDEVOPS_MAX_SESSIONS), causing the legacy override to be ignored; update the
toggle_keys string to include max_interactive_sessions alongside the other keys
so the legacy loader honors the AIDEVOPS_MAX_SESSIONS mapping and keep this list
aligned with _ft_env_map.
In @.agents/scripts/upstream-watch-helper.sh:
- Around line 333-338: The current branch that sets slugs from target_slug
bypasses the config watchlist and later creates a hidden state entry
(.repos[$slug]) for repos not in the config; change the logic so that when
target_slug is provided you validate it exists in the parsed config (from config
and jq '.repos[].slug') and if it is not present reject the operation (return
non-zero and print a clear message) instead of adding .repos[$slug] to state;
ensure the same validation is applied in the other code path that manipulates
.repos[$slug] (the block referenced alongside ack) so untracked repos are never
added to state and ack only treats repos present in the config as watched.
- Around line 662-675: The status output only shows last_release and omits the
last acknowledged commit, so add extraction of last_commit_seen from state
(e.g., last_commit=$(echo "$state" | jq -r --arg slug "$slug"
'.repos[$slug].last_commit_seen // "none"')) and print it alongside
last_release/last_checked; update the block that currently defines last_release,
last_checked, pending and prints those lines to also define last_commit and echo
a "Last commit seen: ${last_commit}" line (conditionally or unconditionally) so
commit-only updates with updates_pending=1 are clearly visible; use the existing
variable names (last_release, last_checked, pending, relevance) and the same
formatting conventions (YELLOW/GREEN/NC) when adding the new output.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 137711e7-8b6c-4198-9a2f-6bbee9e07e4a
📒 Files selected for processing (4)
.agents/AGENTS.md.agents/scripts/shared-constants.sh.agents/scripts/upstream-watch-helper.shTODO.md
|
Dispatching worker to address 5 unresolved review bot suggestions.
|
- Add missing max_interactive_sessions to toggle_keys in shared-constants.sh so AIDEVOPS_MAX_SESSIONS env override works in legacy mode - Validate target slug against watchlist in cmd_check to prevent hidden state entries for untracked repos - Show last_commit_seen in cmd_status output for commit-only update visibility
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
.agents/scripts/upstream-watch-helper.sh (2)
610-616: Consider validating against config for consistency withcmd_check.
cmd_checkvalidates the target slug against the config watchlist (lines 336-339), butcmd_ackvalidates against state. If a repo is manually removed from config but state persists,ackwould still succeed. This is an edge case, but validating against config would be more consistent.♻️ Proposed consistency fix
+ local config + config=$(_read_config) + if ! echo "$config" | jq -e --arg slug "$slug" '.repos[] | select(.slug == $slug)' >/dev/null 2>&1; then + echo -e "${YELLOW}Not watching: ${slug}${NC}" + return 1 + fi + local state state=$(_read_state) - - # Check if we're watching this repo - local existing - existing=$(echo "$state" | jq -r --arg slug "$slug" '.repos[$slug] // empty') - if [[ -z "$existing" ]]; then - echo -e "${YELLOW}Not watching: ${slug}${NC}" - return 1 - fi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.agents/scripts/upstream-watch-helper.sh around lines 610 - 616, The ack path currently checks the slug only against the runtime state (variable existing from state) which can succeed if config was removed; change cmd_ack to validate the target slug against the same config watchlist check used in cmd_check (use the same jq query and config variable used by cmd_check to verify the slug is present in config) before proceeding to query state; update the check that sets existing (and the early return) to first test the slug in config (e.g., same variable/query as cmd_check) and fall back to the state check only if the config validation passes.
100-100: Redundant stderr redirect.
&>/dev/nullalready redirects both stdout and stderr to /dev/null, so the trailing2>&1is a no-op.🧹 Proposed cleanup
- if ! gh auth status &>/dev/null 2>&1; then + if ! gh auth status &>/dev/null; then🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.agents/scripts/upstream-watch-helper.sh at line 100, The conditional invoking the GitHub CLI check uses a redundant stderr redirect in the line containing "if ! gh auth status &>/dev/null 2>&1; then": remove the redundant "2>&1" so the command uses a single redirect ("&>/dev/null") to silence both stdout and stderr, leaving the rest of the conditional logic unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.agents/scripts/upstream-watch-helper.sh:
- Around line 750-753: The --relevance option parsing calls "shift 2" even when
no value follows, causing "shift: can't shift that many" under set -e; update
the --relevance branch to detect whether a following non-option argument exists
before shifting: if a non-empty, non-flag second argument is present, assign it
to relevance and shift 2, otherwise set relevance to empty (or a default) and
only shift 1 to consume the --relevance token. Target the option-parsing block
handling "--relevance" and adjust the logic around relevance="${2:-}" and shift
2 accordingly.
---
Nitpick comments:
In @.agents/scripts/upstream-watch-helper.sh:
- Around line 610-616: The ack path currently checks the slug only against the
runtime state (variable existing from state) which can succeed if config was
removed; change cmd_ack to validate the target slug against the same config
watchlist check used in cmd_check (use the same jq query and config variable
used by cmd_check to verify the slug is present in config) before proceeding to
query state; update the check that sets existing (and the early return) to first
test the slug in config (e.g., same variable/query as cmd_check) and fall back
to the state check only if the config validation passes.
- Line 100: The conditional invoking the GitHub CLI check uses a redundant
stderr redirect in the line containing "if ! gh auth status &>/dev/null 2>&1;
then": remove the redundant "2>&1" so the command uses a single redirect
("&>/dev/null") to silence both stdout and stderr, leaving the rest of the
conditional logic unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: fba77a73-461a-4b6f-903a-06478b713b49
📒 Files selected for processing (2)
.agents/scripts/shared-constants.sh.agents/scripts/upstream-watch-helper.sh
🚧 Files skipped from review as they are similar to previous changes (1)
- .agents/scripts/shared-constants.sh
|
Dispatching worker to address CodeRabbit CHANGES_REQUESTED.
|
…edundant redirect, shift safety - cmd_ack now validates slug against config watchlist (not just state), consistent with cmd_check. Prevents ack succeeding for repos removed from config but with persisting state. - Remove redundant 2>&1 after &>/dev/null in _check_prerequisites. - Safe --relevance option parsing: check arg count before shift 2 to prevent 'can't shift that many' under set -e.
|
Applied all round-3 CodeRabbit review suggestions in bf3c24a:
|
- AGENTS.md domain index: configs/upstream-watch.json -> .agents/configs/upstream-watch.json - reference/services.md: same config path correction - upstream-watch-helper.sh: --relevance without value now returns error instead of silently ignoring
🔍 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: Tue Mar 10 00:11:19 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
marcusquinn
left a comment
There was a problem hiding this comment.
All remaining CodeRabbit findings addressed in 5bd9fd4:
Fixed:
.agents/AGENTS.mddomain index — config path corrected to.agents/configs/upstream-watch.json.agents/reference/services.md— same config path correction--relevancewithout a value — now returns explicit error instead of silently ignoring
Already addressed (prior commits):
cmd_ackconfig validation (nitpick from review 3) — already implemented in bf3c24a (lines 607-613)cmd_ackvalidates against config watchlist, not just state, consistent withcmd_check
Merge conflict resolved:
.task-counter— took main's value (1429)
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
Dispatching worker to address unresolved review suggestions.
|
Address CodeRabbit pre-merge docstring coverage warning (48% -> 100%). All 21 functions now have ###### block docstrings following the project convention used in auto-update-helper.sh and other scripts.
|
Added docstrings to all 21 functions in Review bot status summary:
This PR should be ready for merge. |
🔍 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: Tue Mar 10 01:34:45 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|
Dispatching fix worker for unresolved review suggestions.
|
…m-watch # Conflicts: # TODO.md
🔍 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: Tue Mar 10 02:00:49 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|
|
Audit cross-link: this PR supersedes and completes recovery for closed-unmerged PR #3994, preserving upstream-watch intent on task t1426. |



Summary
upstream-watch-helper.sh(add/remove/check/ack/status) to maintain a watchlist of external repos for passive release monitoringauto-update-helper.shvia 24h-gatedcheck_upstream_watch()— timestamp only advances on successful checkAIDEVOPS_AGENTS_DIRenv var consistently; capturesgh apiexit status withprobe_failedflag;last_commit_seenonly updated on explicitackSupersedes #3994 (rebased, conflicts resolved, all CodeRabbit findings addressed).
Closes #3994
Summary by CodeRabbit
New Features
Documentation