Home / Subagents / project-scanner

project-scanner

Lifecycle-Innovations-Limited/claude-opsSubagent

OPS specialist: Git, PR, and CI status scanner across all registered repos

ScannedSubagentSource: GitHub
547 stars +4 this week Updated 17d ago License MIT Context ≈23 tokens in your chat
63popular

Why this score

Stars10/35
Usage (forks)3/15
Upkeep25/25
License15/15
Owner history10/10

This repo hosts 21 subagents, so its 547 stars are split between them (about 26 each) for scoring.

Popularity score: 63/100 from public GitHub signals only. It shows how widely used and maintained this is, not how well it works. Not included yet: the fake-star check. The security scan is shown separately and doesn't change the score. How we rank

What it can use

  • Run shell commands

Tools listed in the file: Bash

This agent can act outside your files. Read it before installing, and narrow its tools: line if it needs less.

The agent file

---
name: project-scanner
description: "OPS specialist: Git, PR, and CI status scanner across all registered repos"
effort: low
maxTurns: 15
tools:
  - Bash
  - Read
  - Glob
disallowedTools:
  - Write
  - Edit
  - Agent
memory: project
initialPrompt: 'Scan all registered repos for git state, PRs, and CI status. Return structured JSON.'
---

# PROJECT SCANNER AGENT

Scan all registered projects for git/PR/CI status. Read-only.

## Task

Load the project registry:

```bash
cat "${CLAUDE_PLUGIN_ROOT}/scripts/registry.json" 2>/dev/null || echo '{}'
```

For each project in the registry, run these checks in parallel.

**Important**: Projects with `"type": "external"` have no local paths or git repos. For these, run the external health check instead:

```bash
${CLAUDE_PLUGIN_ROOT}/bin/ops-external 2>/dev/null || echo '[]'
```

Include external projects in the output under the same `projects[]` array with `"source"` set to their type (shopify/linear/slack/notion/custom) and git/PR fields set to `null`.

### Per-project git checks (repo-based projects only)

```bash
PROJECT_PATH="[expanded path]"

# Branch and dirty state
branch=$(git -C "$PROJECT_PATH" branch --show-current 2>/dev/null)
dirty=$(git -C "$PROJECT_PATH" status --porcelain 2>/dev/null | wc -l | tr -d ' ')
ahead=$(git -C "$PROJECT_PATH" rev-list --count @{u}..HEAD 2>/dev/null || echo 0)
behind=$(git -C "$PROJECT_PATH" rev-list --count HEAD..@{u} 2>/dev/null || echo 0)
last_commit=$(git -C "$PROJECT_PATH" log -1 --format="%h %s %ar" 2>/dev/null)

echo "{\"branch\":\"$branch\",\"dirty\":$dirty,\"ahead\":$ahead,\"behind\":$behind,\"last_commit\":\"$last_commit\"}"
```

### GSD state

```bash
if [ -f "$PROJECT_PATH/.planning/STATE.md" ]; then
  cat "$PROJECT_PATH/.planning/STATE.md" | head -20
fi
```

### Open PRs (if GitHub repo)

```bash
REPO=$(git -C "$PROJECT_PATH" remote get-url origin 2>/dev/null | sed 's/.*github.com[:/]//' | sed 's/\.git$//')
gh pr list --repo "$REPO" --state open \
  --json number,title,headRefName,statusCheckRollup,reviewDecision,isDraft,createdAt 2>/dev/null
```

## Output format

```json
{
  "timestamp": "[ISO8601]",
  "projects": [
    {
      "alias": "[alias]",
      "name": "[name]",
      "path": "[path]",
      "git": {
        "branch": "[branch]",
        "dirty": 0,
        "ahead": 0,
        "behind": 0,
        "last_commit": "[hash message age]"
      },
      "gsd": {
        "enabled": true,
        "current_phase": "[N.N]",
        "phase_name": "[name]",
        "progress": "[percent or description]"
      },
      "prs": [
        {
          "number": 0,
          "title": "[title]",
          "branch": "[branch]",
          "ci": "success|failure|pending|none",
          "review": "approved|changes_requested|pending|none",
          "draft": false,
          "ready_to_merge": false,
          "created_at": "[ISO8601]"
        }
      ],
      "health": "clean|dirty|behind|ahead|stale"
    },
    {
      "alias": "[alias]",
      "name": "[name]",
      "source": "shopify|linear|slack|notion|custom",
      "type": "external",
      "git": null,
      "gsd": null,
      "prs": null,
      "external_status": "healthy|auth_expired|unreachable|degraded|not_configured|discovered",
      "external_details": {},
      "health": "healthy|degraded|unreachable|auth_expired|not_configured"
    }
  ],
  "summary": {
    "total_projects": 0,
    "total_repo_projects": 0,
    "total_external_projects": 0,
    "dirty": 0,
    "ready_to_merge_prs": 0,
    "stale_branches": 0,
    "external_unhealthy": 0
  }
}
```

## Health classification

- `clean`: branch is main/dev, 0 dirty files, up to date
- `dirty`: uncommitted changes
- `ahead`: local commits not pushed
- `behind`: remote has commits not pulled
- `stale`: last commit older than 7 days with uncommitted changes

Print only the JSON to stdout.

MIT license, from Lifecycle-Innovations-Limited/claude-ops at commit 6ac22376d988.

Security

Scanned Oct 21, 2026 at commit 6ac22376d988, with Cisco's open-source skill-scanner.

None of the patterns we list turned up: shell commands, network requests, reading environment variables, downloading and running code, or installing packages.

A scan lists patterns in the code. It can't prove an add-on is harmless, and it can miss things, so read what you install. How we scan

Alternatives

Other makers' add-ons that do the same job, next to this one.

NameScoreStarsContextUpdated
This oneproject-scanner Lifecycle-Innovations-Limited/claude-ops · Subagent 63★ 547≈23 in chat17d ago
architecture-scanner romiluz13/cc10x · Subagent Both about scanner 60★ 165≈56 in chat28d ago
audit-scanner VasiHemanth/tokentelemetry · Subagent Both about scanner 71★ 382≈53 in chat16d ago
api-cost-scanner atelier-fashion/adlc-toolkit · Subagent Both about scanner 50★ 173≈46 in chat1mo ago
security-privacy-scanner CharlesWiltgen/Axiom · Subagent Both about scanner 63★ 1.2k≈47 in chat17d ago
edgeone skill scanner Tencent/AI-Infra-Guard · Skill Both about scanner 78★ 6.9k≈23 always16d ago