feat: unify update/upgrade CLI, add repo tracking, npm/homebrew packaging#73
feat: unify update/upgrade CLI, add repo tracking, npm/homebrew packaging#73marcusquinn merged 6 commits intomainfrom
Conversation
…ging - Unify update/upgrade commands (both do the same thing) - Add repos.json tracking for initialized projects (~/.config/aidevops/repos.json) - Auto-detect cloned repos with .aidevops.json and offer to register - Add 'aidevops repos' command to list/add/remove/clean registered projects - Add 'aidevops detect' command to scan for unregistered projects - Update aidevops update to check registered projects for version updates - Create bin/aidevops wrapper for npm global install - Create package.json with bin entry and postinstall script - Create homebrew/aidevops.rb formula for Homebrew tap - Add .github/workflows/publish-packages.yml for npm/homebrew releases - Update version-manager.sh release notes for new install methods - Update AGENTS.md documentation with new CLI commands
WalkthroughThis PR adds multi-channel distribution (npm/Homebrew), a bin wrapper and npm postinstall, automated publish workflow, a persistent repos registry with detect/register/upgrade commands, Homebrew formula, docs updates, and minor agent script compatibility and release-note formatting changes. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI as aidevops CLI
participant FS as Filesystem
participant RepoDB as repos.json
User->>CLI: run command (init/status/other)
CLI->>FS: detect .aidevops.json in cwd
alt .aidevops.json present and not registered
CLI->>User: prompt to register project
User->>CLI: confirm registration
CLI->>RepoDB: register_repo(path, version, features)
RepoDB->>FS: write/update repos.json
else registered
CLI->>RepoDB: check_repo_needs_upgrade(path)
alt upgrade needed
CLI->>User: suggest upgrade/propagate version
end
end
sequenceDiagram
participant Dev
participant GHA as GitHub Actions
participant npm as npm Registry
participant GHRel as GitHub Release
participant BrewTap as Homebrew Tap Repo
Dev->>GHA: trigger publish-packages workflow
GHA->>GHA: resolve version (input or VERSION)
GHA->>npm: npm publish (with token)
GHA->>GHRel: fetch release tarball
GHRel->>GHA: provide tarball
GHA->>GHA: compute sha256
GHA->>BrewTap: update formula (version, sha256) and push
GHA->>GHA: emit summary with install instructions
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 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
🧹 Recent nitpick comments
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (1)
🧰 Additional context used📓 Path-based instructions (1)**/*.sh📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (16)📚 Learning: 2025-11-29T04:34:27.158ZApplied to files:
📚 Learning: 2025-11-29T04:34:42.033ZApplied to files:
📚 Learning: 2025-11-29T04:34:30.742ZApplied to files:
📚 Learning: 2026-01-06T15:57:56.027ZApplied to files:
📚 Learning: 2026-01-06T15:57:56.027ZApplied to files:
📚 Learning: 2025-11-29T04:34:42.033ZApplied to files:
📚 Learning: 2025-11-29T04:34:30.742ZApplied to files:
📚 Learning: 2025-12-22T01:24:53.937ZApplied to files:
📚 Learning: 2025-12-22T01:24:53.937ZApplied to files:
📚 Learning: 2026-01-06T15:57:56.027ZApplied to files:
📚 Learning: 2025-12-22T01:24:53.937ZApplied to files:
📚 Learning: 2025-12-22T01:24:53.937ZApplied to files:
📚 Learning: 2025-12-22T01:24:53.937ZApplied to files:
📚 Learning: 2025-12-22T01:25:03.138ZApplied to files:
📚 Learning: 2025-12-22T01:25:03.138ZApplied to files:
📚 Learning: 2025-12-22T01:25:03.138ZApplied to files:
⏰ 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)
🔇 Additional comments (11)
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 significantly enhances the Highlights
Ignored Files
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: Tue Jan 13 22:38:14 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
There was a problem hiding this comment.
Code Review
This pull request introduces significant new features, including repository tracking, auto-detection of projects, and packaging for npm and Homebrew. The changes are extensive and well-structured. I've identified a critical issue in the Homebrew formula that would prevent it from working, along with some high-severity issues related to efficiency and error handling in the main shell script. I've also found a minor issue in the new npm post-install script. My review provides suggestions to address these points to improve the robustness and correctness of the new features.
| # Install the CLI script | ||
| bin.install "aidevops.sh" => "aidevops" |
There was a problem hiding this comment.
The install method in the Homebrew formula has a bug. It installs aidevops.sh to bin/aidevops, but then the wrapper script created later tries to execute aidevops.sh from libexec, where it was never installed. This will cause the aidevops command to fail after installation.
The aidevops.sh script should be installed to libexec instead of bin. The initial bin.install is incorrect and should be changed.
# Install the CLI script to libexec
libexec.install "aidevops.sh"
aidevops.sh
Outdated
| init_repos_file | ||
|
|
||
| # Normalize path (resolve symlinks, remove trailing slash) | ||
| repo_path=$(cd "$repo_path" 2>/dev/null && pwd -P) |
There was a problem hiding this comment.
The path normalization repo_path=$(cd "$repo_path" 2>/dev/null && pwd -P) can result in an empty repo_path if the original path is invalid or doesn't exist. This empty path is then used in subsequent jq commands, which could lead to unexpected behavior like modifying an entry with an empty path or creating a new one. The function should handle this error case explicitly by checking if the path normalization was successful and returning an error if it failed.
| repo_path=$(cd "$repo_path" 2>/dev/null && pwd -P) | |
| local normalized_path | |
| normalized_path=$(cd "$repo_path" 2>/dev/null && pwd -P) | |
| if [[ -z "$normalized_path" ]]; then | |
| print_error "Invalid repository path provided: $1" | |
| return 1 | |
| fi | |
| repo_path="$normalized_path" |
| local removed=0 | ||
| local temp_file="${REPOS_FILE}.tmp" | ||
|
|
||
| # Filter out repos that don't exist | ||
| jq '[.initialized_repos[] | select(.path as $p | ($p | type == "string") and ([$p] | .[0] | test("^/")))]' "$REPOS_FILE" > /dev/null 2>&1 | ||
|
|
||
| while IFS= read -r repo_path; do | ||
| [[ -z "$repo_path" ]] && continue | ||
| if [[ ! -d "$repo_path" ]]; then | ||
| jq --arg path "$repo_path" '.initialized_repos |= map(select(.path != $path))' "$REPOS_FILE" > "$temp_file" && \ | ||
| mv "$temp_file" "$REPOS_FILE" | ||
| print_info "Removed: $repo_path" | ||
| ((removed++)) | ||
| fi | ||
| done < <(get_registered_repos) | ||
|
|
||
| if [[ $removed -eq 0 ]]; then | ||
| print_success "No stale entries found" | ||
| else | ||
| print_success "Removed $removed stale entries" | ||
| fi |
There was a problem hiding this comment.
The current implementation of cmd_repos clean iterates through registered repos and calls jq to remove each stale entry one by one. This is inefficient as it reads and writes the entire repos.json file inside the loop for every non-existent repository. This can be slow if there are many stale entries and is not an atomic operation.
A better approach is to read the file once, determine which repositories to keep, and then write the new list back to the file in a single operation. This is more efficient and safer.
local removed=0
local temp_file="${REPOS_FILE}.tmp"
# Create a temporary file with only the repos that still exist
jq -c '.initialized_repos[]' "$REPOS_FILE" 2>/dev/null | while IFS= read -r repo_json; do
local repo_path
repo_path=$(echo "$repo_json" | jq -r '.path')
if [[ -d "$repo_path" ]]; then
echo "$repo_json"
else
print_info "Removed: $repo_path"
((removed++))
fi
done | jq -s '{"initialized_repos": .}' > "$temp_file"
# Replace the original file
mv "$temp_file" "$REPOS_FILE"
if [[ $removed -eq 0 ]]; then
print_success "No stale entries found"
else
print_success "Removed $removed stale entries"
fi
scripts/npm-postinstall.js
Outdated
| * Runs setup.sh to deploy agents after npm install -g | ||
| */ | ||
|
|
||
| const { execSync, spawn } = require('child_process'); |
There was a problem hiding this comment.
🤖 Augment PR SummarySummary: This PR enhances the Changes:
Technical Notes: The CLI now depends more heavily on 🤖 Was this summary useful? React with 👍 or 👎 |
|
|
||
| const { execSync, spawn } = require('child_process'); | ||
| const path = require('path'); | ||
| const fs = require('fs'); |
There was a problem hiding this comment.
| (bin/"aidevops").write <<~EOS | ||
| #!/usr/bin/env bash | ||
| export AIDEVOPS_SHARE="#{share}/aidevops" | ||
| exec "#{libexec}/aidevops.sh" "$@" |
There was a problem hiding this comment.
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 Fix all issues with AI agents
In @.github/workflows/publish-packages.yml:
- Around line 30-37: The "Get version" step (id: version) directly interpolates
github.event.inputs.version into a run script which can enable script injection;
instead pass the workflow_dispatch input through an environment variable and
reference that env var inside the run block. Update the step to set an env entry
(e.g. VERSION: ${{ github.event.inputs.version }}) and then in the run script
check that env var (falling back to reading the VERSION file) and write to
GITHUB_OUTPUT; keep the existing output key name ("version") and preserve the
same logic but replace all occurrences of `${{ github.event.inputs.version }}`
with the shell-safe environment variable (e.g. $VERSION).
- Around line 79-83: The tarball download may return a 404 and produce an
invalid SHA; make the curl call that populates SHA256 fail on HTTP errors and
abort the step if the download fails. Change the download invocation that
references TARBALL_URL to use curl with the fail-on-error flag (e.g., -f) and
ensure you check the curl exit status before computing/exporting SHA256 (only
write to GITHUB_OUTPUT if curl succeeded), so that a failed download causes the
job to fail instead of writing an invalid SHA.
- Around line 70-83: The step that reads github.event.inputs.version uses direct
workflow interpolation; change it to accept the input via an environment
variable (e.g., INPUT_VERSION) and reference that shell variable inside the
release step and the Homebrew job to avoid injection issues: set env:
INPUT_VERSION: ${{ github.event.inputs.version }} for the step (or job), then in
the script use if [ -n "$INPUT_VERSION" ]; then VERSION="$INPUT_VERSION"; else
VERSION=$(cat VERSION); fi and build TARBALL_URL using "$VERSION" and write
outputs to $GITHUB_OUTPUT as before; apply this same pattern to the Homebrew
job's Get version and SHA step so both use INPUT_VERSION (or similarly named env
var) instead of direct ${{ github.event.inputs.version }} interpolation.
- Around line 91-102: The workflow uses the third-party action reference
dmnemec/copy_file_to_another_repo_action@main which is unpinned; replace the
@main ref with the action's specific commit SHA (e.g.,
dmnemec/copy_file_to_another_repo_action@<commit-sha>) to pin the dependency,
updating the with block only to change the ref and committing that exact SHA so
the Push to homebrew-tap step always uses the immutable, audited version of the
action.
In @aidevops.sh:
- Around line 1474-1500: The remove|rm handler's path normalization fallback
erroneously assigns repo_path from the positional $2; remove the "||
repo_path=\"$2\"" fallback and let repo_path remain as-is if cd/pwd fails (i.e.,
keep the existing repo_path local variable), so the jq removal will use the
originally supplied path variable (repo_path) rather than the wrong positional
parameter.
In @package.json:
- Around line 55-66: Remove the ".agent/" entry from the package.json "files"
array (the files manifest) so the published npm package no longer includes the
4MB developer-only directory; if any specific artifacts from .agent are actually
required at runtime, add only those specific file paths to the "files" array
instead of the whole directory, and ensure "scripts/npm-postinstall.js", "bin/",
"aidevops.sh", "setup.sh", and "VERSION" remain listed.
In @scripts/npm-postinstall.js:
- Around line 55-59: The catch block in scripts/npm-postinstall.js prints an
incorrect manual path (~/.aidevops/setup.sh); update the error output in that
catch to point to the actual package-installed setup script (resolve the package
directory at runtime, e.g. using __dirname or a computed packageDir and
reference packageDir + '/setup.sh') or, as an alternative/fallback, include the
curl installer command suggestion in the message so users have a reliable manual
option; keep the non-failing exit behavior (process.exit(0)) but ensure the log
clearly shows the real install path or the curl fallback.
🧹 Nitpick comments (6)
scripts/npm-postinstall.js (1)
7-7: Remove unusedspawnimport.The
spawnfunction is imported but never used in this script. OnlyexecSyncis utilized.🧹 Proposed fix
-const { execSync, spawn } = require('child_process'); +const { execSync } = require('child_process');homebrew/aidevops.rb (1)
36-39: Add non-interactive mode to post_install for consistency.The npm postinstall script uses
AIDEVOPS_NONINTERACTIVE=1to prevent interactive prompts during automated installation. The Homebrew post_install should follow the same pattern to ensure reliable automated installation.♻️ Proposed fix
def post_install # Run setup to deploy agents - system "bash", "#{libexec}/setup.sh" + ENV["AIDEVOPS_NONINTERACTIVE"] = "1" + system "bash", "#{libexec}/setup.sh" endaidevops.sh (4)
83-112: Add explicit return and handle path normalization failure.Per coding guidelines, shell functions should use explicit returns. Also, the path normalization on line 91 could silently fail if the directory doesn't exist.
♻️ Suggested improvements
register_repo() { local repo_path="$1" local version="$2" local features="$3" init_repos_file # Normalize path (resolve symlinks, remove trailing slash) - repo_path=$(cd "$repo_path" 2>/dev/null && pwd -P) + repo_path=$(cd "$repo_path" 2>/dev/null && pwd -P) || { + print_warning "Cannot access path: $repo_path" + return 1 + } if ! command -v jq &>/dev/null; then print_warning "jq not installed - repo tracking disabled" return 0 fiAnd add explicit return at end:
jq --arg path "$repo_path" --arg version "$version" --arg features "$features" \ '.initialized_repos += [{path: $path, version: $version, features: ($features | split(",")), initialized: (now | strftime("%Y-%m-%dT%H:%M:%SZ"))}]' \ "$REPOS_FILE" > "$temp_file" && mv "$temp_file" "$REPOS_FILE" fi + return 0 }
114-124: Add explicit return for consistency.The function handles the jq dependency gracefully but lacks an explicit return statement at the end.
♻️ Minor fix
jq -r '.initialized_repos[] | .path' "$REPOS_FILE" 2>/dev/null || echo "" + return 0 }
126-148: Clarify version comparison semantics.The comment on line 143 states "simple string comparison works for semver" but string comparison doesn't handle semver correctly (e.g.,
"2.9.0" > "2.10.0"lexicographically). However, since the function checks for any version difference rather than "older", this is functionally acceptable for triggering update prompts.Consider updating the comment to be more accurate:
♻️ Clarify comment
- # Compare versions (simple string comparison works for semver) + # Compare versions (checks for any difference, not semantic ordering) if [[ "$repo_version" != "$current_version" ]]; then
1514-1516: Remove unused jq validation line.Line 1515 executes a complex jq command but redirects output to
/dev/null, making it effectively dead code. This appears to be a leftover from debugging or an incomplete validation check.♻️ Remove dead code
local removed=0 local temp_file="${REPOS_FILE}.tmp" - # Filter out repos that don't exist - jq '[.initialized_repos[] | select(.path as $p | ($p | type == "string") and ([$p] | .[0] | test("^/")))]' "$REPOS_FILE" > /dev/null 2>&1 - while IFS= read -r repo_path; do
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
.agent/AGENTS.md.agent/scripts/full-loop-helper.sh.agent/scripts/version-manager.sh.github/workflows/publish-packages.ymlaidevops.shbin/aidevopshomebrew/aidevops.rbpackage.jsonscripts/npm-postinstall.js
🧰 Additional context used
📓 Path-based instructions (3)
.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/full-loop-helper.sh.agent/scripts/version-manager.sh
**/*.sh
📄 CodeRabbit inference engine (AGENTS.md)
**/*.sh: Use local var="$1" pattern for shell variable assignments
Use explicit returns in shell scripts
Run ShellCheck on all scripts with zero violations required
Files:
aidevops.sh
**/.agent/scripts/version-manager.sh
📄 CodeRabbit inference engine (AGENTS.md)
Use .agent/scripts/version-manager.sh release [major|minor|patch] for releases
Files:
.agent/scripts/version-manager.sh
🧠 Learnings (17)
📚 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:
bin/aidevops.agent/AGENTS.mdaidevops.shscripts/npm-postinstall.jshomebrew/aidevops.rb
📚 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: Reference the authoritative repository at ~/Git/aidevops/ for all detailed AI assistant instructions and configurations
Applied to files:
bin/aidevops.agent/AGENTS.mdaidevops.shhomebrew/aidevops.rbpackage.json
📚 Learning: 2025-12-22T01:25:03.138Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: templates/home/git/AGENTS.md:0-0
Timestamp: 2025-12-22T01:25:03.138Z
Learning: Use standardized patterns as defined in the authoritative DevOps repository at ~/Git/aidevops/
Applied to files:
bin/aidevopsaidevops.sh
📚 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: Use the helper script at ~/Git/aidevops/.agent/scripts/setup-local-api-keys.sh to manage secure storage of API keys rather than manual configuration
Applied to files:
bin/aidevops.agent/AGENTS.mdaidevops.sh
📚 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: 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: Maintain all instructions, documentation, and operational guidance in AGENTS.md as the single source of truth
Applied to files:
.agent/AGENTS.md
📚 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: Maintain all AI assistant instructions, documentation, and operational guidance 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: 2026-01-06T15:57:56.027Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-06T15:57:56.027Z
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: 2026-01-06T15:57:56.027Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-06T15:57:56.027Z
Learning: Applies to **/AGENTS.md : Use progressive disclosure in AGENTS.md with pointers to subagents rather than inline content
Applied to files:
.agent/AGENTS.md
📚 Learning: 2026-01-06T15:57:56.027Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-06T15:57:56.027Z
Learning: Applies to **/setup.sh : Deploy agents locally using ./setup.sh script
Applied to files:
.agent/AGENTS.mdaidevops.shscripts/npm-postinstall.js
📚 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: Use only the specified working directories: ~/.aidevops/.agent-workspace/work/[project]/ for work files, ~/.aidevops/.agent-workspace/tmp/ for temporary files, and ~/.aidevops/.agent-workspace/memory/ for persistent memory
Applied to files:
.agent/AGENTS.mdaidevops.sh
📚 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: Never store credentials in working directories (~/.aidevops/.agent-workspace/), Git repositories, home directory root, or hardcoded in code and scripts
Applied to files:
aidevops.sh
📚 Learning: 2025-12-22T01:25:03.138Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: templates/home/git/AGENTS.md:0-0
Timestamp: 2025-12-22T01:25:03.138Z
Learning: Store Service Configurations in ~/Git/aidevops/configs/[service]-config.json with file permissions set to 600
Applied to files:
aidevops.sh
📚 Learning: 2025-12-22T01:25:03.138Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: templates/home/git/AGENTS.md:0-0
Timestamp: 2025-12-22T01:25:03.138Z
Learning: NEVER store credentials or API keys in ~/.aidevops/.agent-workspace/ directories - working files are not secure
Applied to files:
aidevops.sh
📚 Learning: 2026-01-06T15:57:56.027Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-06T15:57:56.027Z
Learning: Applies to **/.agent/scripts/version-manager.sh : Use .agent/scripts/version-manager.sh release [major|minor|patch] for releases
Applied to files:
.agent/scripts/version-manager.sh
🪛 GitHub Check: Codacy Static Code Analysis
.github/workflows/publish-packages.yml
[failure] 32-32: .github/workflows/publish-packages.yml#L32
Using variable interpolation ${{...}} with github context data in a run: step could allow an attacker to inject their own code into the runner.
[warning] 92-92: .github/workflows/publish-packages.yml#L92
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release.
scripts/npm-postinstall.js
[warning] 1-1: scripts/npm-postinstall.js#L1
ES2023 Hashbang comments are forbidden.
[warning] 1-1: scripts/npm-postinstall.js#L1
This file needs no shebang.
[warning] 1-1: scripts/npm-postinstall.js#L1
This file needs no shebang.
[notice] 1-1: scripts/npm-postinstall.js#L1
You have a misspelled word: usr on Comment
[warning] 7-7: scripts/npm-postinstall.js#L7
'spawn' is assigned a value but never used.
[warning] 7-7: scripts/npm-postinstall.js#L7
'spawn' is assigned a value but never used.
[warning] 7-7: scripts/npm-postinstall.js#L7
'spawn' is assigned a value but never used.
[warning] 7-7: scripts/npm-postinstall.js#L7
A require() style import is forbidden.
[warning] 7-7: scripts/npm-postinstall.js#L7
ES2015 block-scoped variables are forbidden.
[warning] 7-7: scripts/npm-postinstall.js#L7
ES2015 destructuring is forbidden.
[notice] 7-7: scripts/npm-postinstall.js#L7
Filename npm-postinstall.js does not match the file name pattern ^([a-z][a-z0-9])(-[a-z0-9]+)(.spec|.test)?.ts$
[warning] 7-7: scripts/npm-postinstall.js#L7
Require statement not part of import statement.
[warning] 8-8: scripts/npm-postinstall.js#L8
A require() style import is forbidden.
[warning] 8-8: scripts/npm-postinstall.js#L8
ES2015 block-scoped variables are forbidden.
[warning] 8-8: scripts/npm-postinstall.js#L8
Require statement not part of import statement.
[warning] 9-9: scripts/npm-postinstall.js#L9
A require() style import is forbidden.
[warning] 9-9: scripts/npm-postinstall.js#L9
ES2015 block-scoped variables are forbidden.
[warning] 9-9: scripts/npm-postinstall.js#L9
Require statement not part of import statement.
[notice] 9-9: scripts/npm-postinstall.js#L9
You have a misspelled word: fs on Identifier
[warning] 11-11: scripts/npm-postinstall.js#L11
ES2015 block-scoped variables are forbidden.
[warning] 12-12: scripts/npm-postinstall.js#L12
ES2015 block-scoped variables are forbidden.
[warning] 13-13: scripts/npm-postinstall.js#L13
A require() style import is forbidden.
[warning] 13-13: scripts/npm-postinstall.js#L13
ES2015 block-scoped variables are forbidden.
[warning] 13-13: scripts/npm-postinstall.js#L13
Require statement not part of import statement.
[notice] 13-13: scripts/npm-postinstall.js#L13
You have a misspelled word: os on String
[warning] 16-16: scripts/npm-postinstall.js#L16
ES2015 block-scoped variables are forbidden.
[warning] 16-16: scripts/npm-postinstall.js#L16
npm_config_global is not listed as a dependency in turbo.json
[warning] 17-17: scripts/npm-postinstall.js#L17
Prefer '_.includes' over the native function.
⏰ 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 (16)
.agent/scripts/full-loop-helper.sh (1)
49-50: LGTM!Clean addition that completes the legacy path constants symmetrically. The shellcheck disable annotation is appropriate since this constant serves documentation and future compatibility purposes, mirroring the existing
LEGACY_STATE_DIRpattern on lines 47-48.scripts/npm-postinstall.js (1)
15-24: Global detection relies primarily onnpm_config_global(correct).The
process.argvchecks on lines 17-18 are ineffective during postinstall execution since npm doesn't forward the-g/--globalflags to hook scripts. However, this is harmless since thenpm_config_globalenvironment variable on line 16 is the canonical detection method and will work correctly.The overall skip logic is sound for preventing redundant setup in development environments.
.agent/scripts/version-manager.sh (1)
598-648: LGTM! Release notes template updated for multi-channel distribution.The updated
generate_release_notes()template now accurately reflects the new installation methods introduced in this PR:
- npm global install
- Homebrew tap
- curl installer
The structure follows good release note practices with clear sections for installation, quick start, documentation, and links. This aligns well with the PR's goal of establishing npm and Homebrew as distribution channels.
bin/aidevops (1)
1-21: LGTM! Clean and minimal wrapper with proper error handling.The wrapper script follows best practices:
- Strict mode (
set -euo pipefail) catches errors early- Uses
execto efficiently replace the wrapper process- Provides helpful error messages with installation guidance
The hardcoded fallback path
$HOME/Git/aidevops/aidevops.shon line 14-16 is a reasonable developer convenience, though users with non-standard layouts would need to use npm/brew installs. This tradeoff is acceptable for maintaining simplicity.homebrew/aidevops.rb (1)
8-9: SHA256 placeholder is correctly handled by CI workflow.The publish-packages workflow's
update-homebrew-tapjob dynamically computes the SHA256 hash directly from the release tarball usingcurlandsha256sum, then substitutes it into the formula viasedbefore pushing to the homebrew-tap repository. The PLACEHOLDER_SHA256 will be properly replaced during release publication..agent/AGENTS.md (2)
410-423: LGTM! Clear multi-channel installation documentation.The installation section now properly documents npm, Homebrew, and curl methods. This aligns well with the new distribution infrastructure added in this PR.
443-454: Well-documented CLI surface expansion.The new commands (
update,upgrade,repos,repos add,detect,update-tools) are clearly documented with their purposes. The project tracking and auto-detection sections provide useful context for users discovering these features.aidevops.sh (6)
73-79: LGTM! Clean initialization function.The
init_repos_filefunction follows good practices with directory creation before file write. The JSON structure is properly initialized.
150-180: LGTM! Well-structured detection function.The function properly handles edge cases (not in git repo, no .aidevops.json, already registered) with appropriate return codes. Good use of explicit returns.
520-573: LGTM! Solid repo upgrade flow.The implementation properly:
- Iterates registered repos with process substitution
- Checks directory existence before processing
- Uses atomic temp file writes for JSON updates
- Provides clear user feedback
Good integration of the repo tracking feature into the update workflow.
994-1006: LGTM! Clean feature list construction and registration.The features_list is properly built with comma separation and trailing comma removal. Registration happens at the appropriate point after all initialization completes.
1546-1626: LGTM! Safe and thorough project detection.The implementation properly uses
find -print0withread -d ''for safe filename handling. The two-phase approach (current directory first, then ~/Git scan) provides good UX. User prompts are clear with sensible defaults.
1691-1697: LGTM! Helpful auto-detection hook.The auto-detection tip is a nice UX touch, properly excluding the
detectandreposcommands to avoid redundant messaging. Good use of stderr redirect to suppress noise.package.json (2)
7-9: LGTM! Proper bin entry for CLI exposure.The bin entry correctly maps the
aidevopscommand to the wrapper script at./bin/aidevops.
21-22: LGTM! Resilient postinstall hook.The
|| trueensures npm install doesn't fail if the postinstall script encounters issues, which is appropriate for optional setup steps..github/workflows/publish-packages.yml (1)
1-58: LGTM! Well-structured npm publish job.The npm publishing job follows best practices:
- Uses provenance for supply chain transparency
- Handles both release triggers and manual dispatch
- Updates package.json version before publish
- Provides clear step summary
| def install | ||
| # Install the CLI script | ||
| bin.install "aidevops.sh" => "aidevops" | ||
|
|
||
| # Install setup script for manual setup | ||
| libexec.install "setup.sh" | ||
|
|
||
| # Install agent files | ||
| (share/"aidevops").install ".agent" | ||
| (share/"aidevops").install "VERSION" | ||
|
|
||
| # Create wrapper that sets up paths | ||
| (bin/"aidevops").write <<~EOS | ||
| #!/usr/bin/env bash | ||
| export AIDEVOPS_SHARE="#{share}/aidevops" | ||
| exec "#{libexec}/aidevops.sh" "$@" | ||
| EOS | ||
| end |
There was a problem hiding this comment.
Path mismatch: wrapper references wrong script name.
Line 19 installs aidevops.sh as aidevops in the bin directory, but line 32 in the wrapper tries to execute #{libexec}/aidevops.sh. Since the setup script is installed to libexec (line 22), not the main script, and the main script is renamed in bin, this wrapper will fail to find the script.
Additionally, the wrapper overwrites the binary just installed on line 19, which seems intentional but the exec path is incorrect.
🐛 Proposed fix - align paths correctly
def install
# Install the CLI script
- bin.install "aidevops.sh" => "aidevops"
+ libexec.install "aidevops.sh"
# Install setup script for manual setup
libexec.install "setup.sh"
# Install agent files
(share/"aidevops").install ".agent"
(share/"aidevops").install "VERSION"
# Create wrapper that sets up paths
(bin/"aidevops").write <<~EOS
#!/usr/bin/env bash
export AIDEVOPS_SHARE="#{share}/aidevops"
exec "#{libexec}/aidevops.sh" "$@"
EOS
end📝 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.
| def install | |
| # Install the CLI script | |
| bin.install "aidevops.sh" => "aidevops" | |
| # Install setup script for manual setup | |
| libexec.install "setup.sh" | |
| # Install agent files | |
| (share/"aidevops").install ".agent" | |
| (share/"aidevops").install "VERSION" | |
| # Create wrapper that sets up paths | |
| (bin/"aidevops").write <<~EOS | |
| #!/usr/bin/env bash | |
| export AIDEVOPS_SHARE="#{share}/aidevops" | |
| exec "#{libexec}/aidevops.sh" "$@" | |
| EOS | |
| end | |
| def install | |
| # Install the CLI script | |
| libexec.install "aidevops.sh" | |
| # Install setup script for manual setup | |
| libexec.install "setup.sh" | |
| # Install agent files | |
| (share/"aidevops").install ".agent" | |
| (share/"aidevops").install "VERSION" | |
| # Create wrapper that sets up paths | |
| (bin/"aidevops").write <<~EOS | |
| #!/usr/bin/env bash | |
| export AIDEVOPS_SHARE="#{share}/aidevops" | |
| exec "#{libexec}/aidevops.sh" "$@" | |
| EOS | |
| end |
- Security: Use env vars instead of direct interpolation in workflow - Security: Pin third-party action to commit SHA - Security: Add fail-on-error to tarball download - Fix: Correct path fallback in remove|rm handler - Fix: Remove unused spawn import in postinstall.js - Fix: Correct error message path in postinstall.js - Fix: Add explicit returns to shell functions - Fix: Remove dead jq validation code - Optimize: Remove .agent/ from npm package (setup.sh downloads it) - Improve: Add non-interactive mode to Homebrew post_install
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @aidevops.sh:
- Around line 155-185: In detect_unregistered_repo(), the git rev-parse
--is-inside-work-tree call uses redundant redirection (&>/dev/null 2>&1); remove
the duplicate so the command redirects both stdout and stderr only once (e.g.,
use &>/dev/null or >/dev/null 2>&1) to avoid the double-stderr redirection and
keep behavior unchanged.
- Around line 1518-1536: The arithmetic increment using "((removed++))" can
return a non-zero exit status under set -e when removed is 0; replace that
increment with a safe form such as "((removed+=1))" or "removed=$((removed+1))"
in the block that initializes "local removed=0" and increments inside the loop
that reads from get_registered_repos so the script won't abort unexpectedly.
In @package.json:
- Around line 59-65: The package.json "files" array is missing the templates
directory required by npm-postinstall.js and setup.sh; update the "files" array
entry used in package.json to include "templates/" so that setup.sh (which calls
templates/deploy-templates.sh at line 1091) and npm-postinstall.js can find and
execute deploy-templates.sh and other template scripts during global installs.
🧹 Nitpick comments (2)
aidevops.sh (2)
73-79: Add explicit return for consistency.Per coding guidelines, shell functions should have explicit returns.
♻️ Suggested fix
init_repos_file() { if [[ ! -f "$REPOS_FILE" ]]; then mkdir -p "$CONFIG_DIR" echo '{"initialized_repos": []}' > "$REPOS_FILE" fi + return 0 }
1583-1600: Consider adding explicit return at end of cmd_detect.For consistency with coding guidelines requiring explicit returns in shell functions.
♻️ Suggested addition at end of cmd_detect
done fi + return 0 }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
.github/workflows/publish-packages.ymlaidevops.shhomebrew/aidevops.rbpackage.jsonscripts/npm-postinstall.js
🚧 Files skipped from review as they are similar to previous changes (2)
- homebrew/aidevops.rb
- .github/workflows/publish-packages.yml
🧰 Additional context used
📓 Path-based instructions (1)
**/*.sh
📄 CodeRabbit inference engine (AGENTS.md)
**/*.sh: Use local var="$1" pattern for shell variable assignments
Use explicit returns in shell scripts
Run ShellCheck on all scripts with zero violations required
Files:
aidevops.sh
🧠 Learnings (10)
📚 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:
aidevops.shpackage.jsonscripts/npm-postinstall.js
📚 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: Use only the specified working directories: ~/.aidevops/.agent-workspace/work/[project]/ for work files, ~/.aidevops/.agent-workspace/tmp/ for temporary files, and ~/.aidevops/.agent-workspace/memory/ for persistent memory
Applied to files:
aidevops.sh
📚 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: Never store credentials in working directories (~/.aidevops/.agent-workspace/), Git repositories, home directory root, or hardcoded in code and scripts
Applied to files:
aidevops.sh
📚 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: Reference the authoritative repository at ~/Git/aidevops/ for all detailed AI assistant instructions and configurations
Applied to files:
aidevops.shpackage.json
📚 Learning: 2025-12-22T01:25:03.138Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: templates/home/git/AGENTS.md:0-0
Timestamp: 2025-12-22T01:25:03.138Z
Learning: Store Service Configurations in ~/Git/aidevops/configs/[service]-config.json with file permissions set to 600
Applied to files:
aidevops.sh
📚 Learning: 2025-12-22T01:25:03.138Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: templates/home/git/AGENTS.md:0-0
Timestamp: 2025-12-22T01:25:03.138Z
Learning: Use standardized patterns as defined in the authoritative DevOps repository at ~/Git/aidevops/
Applied to files:
aidevops.sh
📚 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: Use the helper script at ~/Git/aidevops/.agent/scripts/setup-local-api-keys.sh to manage secure storage of API keys rather than manual configuration
Applied to files:
aidevops.sh
📚 Learning: 2026-01-06T15:57:56.027Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-06T15:57:56.027Z
Learning: Applies to **/setup.sh : Deploy agents locally using ./setup.sh script
Applied to files:
aidevops.shscripts/npm-postinstall.js
📚 Learning: 2025-12-22T01:25:03.138Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: templates/home/git/AGENTS.md:0-0
Timestamp: 2025-12-22T01:25:03.138Z
Learning: NEVER store credentials or API keys in ~/.aidevops/.agent-workspace/ directories - working files are not secure
Applied to files:
aidevops.sh
📚 Learning: 2026-01-06T15:57:56.027Z
Learnt from: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-06T15:57:56.027Z
Learning: Applies to **/AGENTS.md : Limit root AGENTS.md to ~50-100 max instructions with universal applicability to >80% of tasks
Applied to files:
package.json
🪛 GitHub Check: Codacy Static Code Analysis
scripts/npm-postinstall.js
[warning] 6-6: scripts/npm-postinstall.js#L6
A require() style import is forbidden.
[warning] 6-6: scripts/npm-postinstall.js#L6
ES2015 block-scoped variables are forbidden.
[warning] 6-6: scripts/npm-postinstall.js#L6
ES2015 destructuring is forbidden.
[notice] 6-6: scripts/npm-postinstall.js#L6
Filename npm-postinstall.js does not match the file name pattern ^([a-z][a-z0-9])(-[a-z0-9]+)(.spec|.test)?.ts$
[warning] 6-6: scripts/npm-postinstall.js#L6
Require statement not part of import statement.
[warning] 7-7: scripts/npm-postinstall.js#L7
A require() style import is forbidden.
[warning] 7-7: scripts/npm-postinstall.js#L7
ES2015 block-scoped variables are forbidden.
[warning] 7-7: scripts/npm-postinstall.js#L7
Require statement not part of import statement.
[warning] 8-8: scripts/npm-postinstall.js#L8
A require() style import is forbidden.
[warning] 8-8: scripts/npm-postinstall.js#L8
ES2015 block-scoped variables are forbidden.
[warning] 8-8: scripts/npm-postinstall.js#L8
Require statement not part of import statement.
[notice] 8-8: scripts/npm-postinstall.js#L8
You have a misspelled word: fs on Identifier
[warning] 9-9: scripts/npm-postinstall.js#L9
A require() style import is forbidden.
[warning] 9-9: scripts/npm-postinstall.js#L9
ES2015 block-scoped variables are forbidden.
[warning] 9-9: scripts/npm-postinstall.js#L9
Require statement not part of import statement.
[notice] 9-9: scripts/npm-postinstall.js#L9
You have a misspelled word: os on Identifier
[warning] 11-11: scripts/npm-postinstall.js#L11
ES2015 block-scoped variables are forbidden.
[warning] 12-12: scripts/npm-postinstall.js#L12
ES2015 block-scoped variables are forbidden.
[warning] 13-13: scripts/npm-postinstall.js#L13
ES2015 block-scoped variables are forbidden.
[notice] 13-13: scripts/npm-postinstall.js#L13
You have a misspelled word: os on Identifier
[warning] 16-16: scripts/npm-postinstall.js#L16
ES2015 block-scoped variables are forbidden.
[warning] 16-16: scripts/npm-postinstall.js#L16
npm_config_global is not listed as a dependency in turbo.json
[warning] 19-19: scripts/npm-postinstall.js#L19
Found existsSync from package "fs" with non literal argument at index 0
[failure] 19-19: scripts/npm-postinstall.js#L19
The application dynamically constructs file or path information.
[notice] 19-19: scripts/npm-postinstall.js#L19
You have a misspelled word: fs on Identifier
[notice] 20-20: scripts/npm-postinstall.js#L20
You have a misspelled word: aidevops on String
[failure] 25-25: scripts/npm-postinstall.js#L25
The application dynamically constructs file or path information.
[notice] 25-25: scripts/npm-postinstall.js#L25
You have a misspelled word: fs on Identifier
[notice] 30-30: scripts/npm-postinstall.js#L30
You have a misspelled word: aidevops on String
[warning] 35-35: scripts/npm-postinstall.js#L35
ES2015 template literals are forbidden.
⏰ 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)
scripts/npm-postinstall.js (3)
1-13: LGTM! Clean setup for the postinstall script.The CommonJS imports and path construction are appropriate for a Node.js postinstall script. The static analysis warnings about ES2015 features and require() are false positives—this is intentionally a CommonJS script for broad Node.js compatibility.
15-22: Verify the skip condition logic.The condition
!isGlobalInstall && fs.existsSync(agentsDir)skips setup only when it's a local install AND agents already exist. This means:
- Local install without agents → runs setup (may be unintended)
- Global install → always runs setup
If the intent is to skip all local installs regardless of agent state, consider:
-if (!isGlobalInstall && fs.existsSync(agentsDir)) { +if (!isGlobalInstall) {Otherwise, if the current behavior is intentional (run setup on fresh local installs), a clarifying comment would help.
33-58: Solid error handling with user-friendly fallback guidance.The non-fatal exit (code 0) ensures npm install doesn't fail if setup encounters issues, and the console output provides clear manual recovery steps. The
stdio: 'inherit'correctly streams setup output to the user.package.json (3)
7-9: LGTM! Clean bin entry for CLI exposure.The bin entry correctly points to the wrapper script, enabling
aidevopscommand after global npm install.
21-22: Appropriate postinstall configuration.The
|| truesuffix ensures npm install succeeds even if postinstall fails, matching the non-fatal error handling in the script itself.
55-58: Verify Windows exclusion is intentional.The
osfield restricts installation to darwin and linux. If Windows/WSL users attemptnpm install -g aidevops, npm will refuse to install. Consider whether this is the desired behavior or if a warning in the README would be more appropriate.aidevops.sh (6)
22-26: LGTM! Well-organized configuration constants.The
CONFIG_DIRandREPOS_FILEpaths follow XDG conventions (~/.config/aidevops), and the ShellCheck disable comment is appropriate for the unusedREPO_URLvariable.
83-116: Clean implementation with proper local variable pattern.The function correctly uses
local var="$1"pattern, handles path normalization failures gracefully, and has explicit returns. The jq-based JSON manipulation is robust.
525-578: Solid upgrade workflow with user confirmation.The registered repos upgrade flow is well-implemented:
- Collects repos needing upgrade into an array
- Displays clear summary before prompting
- Updates both
.aidevops.jsonand the registry atomicallyMinor: The nested while-read loop with jq and temp files is correct but verbose—acceptable for maintainability.
1396-1448: Well-structured repos list command with visual status indicators.The color-coded status display (✓ up-to-date, ↑ update available, ✗ not found) provides excellent UX. The pipe-delimited parsing from jq output is a clean approach.
1550-1630: cmd_detect implementation is thorough and user-friendly.The function handles both current-directory detection and scanning
~/Git/for unregistered projects. The-print0withread -d ''is the correct approach for handling paths with spaces.
1692-1701: Auto-detect tip is a nice UX touch.Silently checking for unregistered repos and showing a non-blocking tip improves discoverability of the registration feature without interrupting workflow.
The npm-postinstall.js uses CommonJS for Node.js compatibility. False positives: spelling (fs, os, aidevops), ES2015 features, TypeScript rules on JS file, path traversal (package-relative paths).
- Remove redundant redirection in detect_unregistered_repo() - Use safe arithmetic increment (removed=$((removed+1))) to avoid set -e issues - Add explicit returns to init_repos_file() and cmd_detect() - Include templates/ in package.json files array for setup.sh
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
🔍 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 Jan 13 23:10:31 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |



Summary
update/upgradecommands (both do the same thing)repos.jsontracking for initialized projects.aidevops.jsonNew CLI Commands
aidevops reposaidevops repos addaidevops repos removeaidevops repos cleanaidevops detectInstallation Methods
Changes
aidevops.sh- Added repo tracking functions, repos/detect commandspackage.json- Added bin entry for npm global installbin/aidevops- Wrapper script for npmscripts/npm-postinstall.js- Runs setup after npm installhomebrew/aidevops.rb- Homebrew formula.github/workflows/publish-packages.yml- Auto-publish on release.agent/AGENTS.md- Updated documentation.agent/scripts/version-manager.sh- Updated release notesNext Steps After Merge
aidevopsnamemarcusquinn/homebrew-taprepo withFormula/directoryHOMEBREW_TAP_TOKENsecret for tap updatesSummary by CodeRabbit
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.