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
12 changes: 10 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
},
"metadata": {
"description": "Automation skills for GitHub org maintenance",
"version": "1.0.0"
"version": "0.1.0"
},
"plugins": [
{
Expand Down Expand Up @@ -95,7 +95,15 @@
"source": "./",
"strict": false,
"skills": [
"./skills/repoman"
"./skills/repoman",
"./skills/link-health-scanner",
"./skills/link-health-fixer",
"./skills/dep-bump-scanner",
"./skills/dep-bump-fixer",
"./skills/github-pr-review",
"./skills/repo-sync",
"./skills/automation-health-dashboard",
"./skills/github-weekly-report"
]
}
]
Expand Down
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Changelog

All notable changes to this project are documented here. The format is based on
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.0] - 2026-10-23

First tagged release of RepoMan, distributed through the `rossoctl-agent-skills`
marketplace.

RepoMan runs automated maintenance **programs** across a set of GitHub repos you
enroll once, handling the capability checks and output wiring for you. `/repoman` is
a single intent-dispatching entrypoint that infers whether you are setting up,
enabling a program, or running one.

### Added

- **Self-contained `repoman` plugin.** One install bundles the `/repoman` entrypoint,
every program skill, and the engine scripts, so you install once and enable more
programs on the fly. The engine is vendored into the plugin and resolved at runtime
via `${CLAUDE_PLUGIN_ROOT}` — no separate automation checkout is required.
- **Six programs** ship ready to enable: `link-health` (scanner + fixer),
`dep-bump` (scanner + fixer), `pr-review`, `repo-sync`, `automation-health`, and
`weekly-report`.
- **Standalone program plugins** remain installable on their own, for using a single
program (for example a one-off PR review) without the full RepoMan bundle.
- **Provenance stamp** (`_vendor.json`) records the exact `rossoctl/automation` commit
the bundled engine was vendored from, so a shipped bundle is traceable to its source.

### Changed

- `marketplace.json` version reconciled to `0.1.0`.
- All skills now declare `bash` 3.2+ and run on the macOS system default.

### Notes

- Engine development lives in `rossoctl/automation`; engine fixes reach every RepoMan
user through a single `repoman` plugin update.

### Contributors

Gloire Rubambiza, Aleksander Slominski, Mariusz Sabath, Jim Cadden.

[0.1.0]: https://github.com/rossoctl/agent-skills/releases/tag/v0.1.0
34 changes: 24 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Built to the [Agent Skills specification](https://agentskills.io/specification).

| Skill | Description |
|-------|-------------|
| [repoman](skills/repoman/) | The RepoMan entrypoint — first-time setup, enabling a program, enrolling repos or an org, or running a program across enrolled repos; a single intent-dispatching skill |
| [repoman](skills/repoman/) | The RepoMan entrypoint and self-contained bundle — first-time setup, enabling a program, enrolling repos or an org, running a program; ships every program skill + the engine so you install once and enable programs on the fly |
| [link-health-scanner](skills/link-health-scanner/) | Scan repos for broken links, create GitHub issues for findings |
| [link-health-fixer](skills/link-health-fixer/) | Re-verify and fix broken links, open PRs for fixes |
| [dep-bump-scanner](skills/dep-bump-scanner/) | Monitor Dependabot PRs, classify by severity, flag SLA breaches |
Expand All @@ -29,14 +29,24 @@ Built to the [Agent Skills specification](https://agentskills.io/specification).
/plugin install <plugin-name>@rossoctl-agent-skills
```

Install one plugin at a time. Replace `<plugin-name>` with a plugin name such as
`repoman`, `link-health`, `dep-bump`, `pr-review`, `automation-health`, or
`repo-sync`. Plugin names are the ones declared in the marketplace, which can
differ from the per-skill directory names in the [Skills](#skills) table. For
example, the `link-health` plugin bundles the `link-health-scanner` and
`link-health-fixer` skills. Run `/plugin` after adding the marketplace to browse
the authoritative list. Installing one plugin does **not** pull in the others,
so repeat the `install` line per plugin you want.
**Recommended: install `repoman`.** The `repoman` plugin is self-contained — it
bundles the RepoMan entrypoint, every program skill (link-health, dep-bump,
pr-review, repo-sync, automation-health, weekly-report) with their scanner and
fixer skills, and the engine scripts. One install gives you the whole system and
lets you enable more programs on the fly:

```
/plugin install repoman@rossoctl-agent-skills
```

**Or install a single program standalone.** Each program is also published as its
own plugin, for using it on its own (e.g. a one-off PR review) without the full
RepoMan bundle. Replace `<plugin-name>` with a plugin name such as `link-health`,
`dep-bump`, `pr-review`, `automation-health`, or `repo-sync`. Plugin names are the
ones declared in the marketplace, which can differ from the per-skill directory
names in the [Skills](#skills) table. Run `/plugin` after adding the marketplace to
browse the authoritative list. Installing one standalone plugin does **not** pull
in the others, so repeat the `install` line per plugin you want.

### Updating

Expand All @@ -48,6 +58,9 @@ update any installed plugins (a Claude Code restart applies plugin updates):
/plugin update <plugin-name>@rossoctl-agent-skills
```

Updating `repoman` refreshes the bundled engine scripts too, so engine fixes reach
every RepoMan user through a single plugin update.

### Manual

Copy the desired skill directory into your project's `.claude/skills/` directory:
Expand All @@ -60,7 +73,8 @@ cp -r skills/link-health-scanner /path/to/project/.claude/skills/

All skills in this repo require:

- `bash` 4+
- `bash` 3.2+ — every skill runs on the macOS system default; no bash-4 features
are used.
- `gh` (GitHub CLI, authenticated)
- `jq`

Expand Down
64 changes: 64 additions & 0 deletions scripts/vendor-engine.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env bash
set -uo pipefail
# Vendor the RepoMan engine from an automation checkout into the repoman plugin's
# flat scripts dir, then stamp the source commit SHA for provenance.
#
# Explicit manifest (never a glob) so this can only ever populate the repoman
# plugin — it must never touch a standalone skill's scripts/ (see agent-skills#51).
# Part of the RepoMan v0.1.0 packaged release (epic rossoctl/automation#72).
#
# vendor-engine.sh --source <automation-repo> --dest <repoman-scripts-dir>

SRC="" DEST=""
while [ $# -gt 0 ]; do
case "$1" in
--source) SRC="${2:-}"; shift 2 ;;
--dest) DEST="${2:-}"; shift 2 ;;
*) echo "ERROR: unknown arg: $1" >&2; exit 2 ;;
esac
done
[ -n "$SRC" ] && [ -n "$DEST" ] || { echo "ERROR: --source and --dest are required" >&2; exit 2; }

# The 23 engine scripts. Flat set: nearly all source program-lib.sh,
# which sources core.sh/github-api.sh/fork.sh/org.sh/repoman-requirements.sh.
MANIFEST="automation-health-dashboard core dep-bump-fixer dep-bump-scanner \
extract-broken-links fork github-api link-health-fixer link-health-scanner \
org parse-diff-map pr-review-fixer pr-review-impact pr-review-lib \
pr-review-scanner program-lib repo-sync repoman-check repoman-index \
repoman-requirements repoman-run repoman-setup weekly-report"

# Pre-validate the WHOLE manifest before copying anything, so a source missing
# late in the list cannot leave a half-vendored dest with a stale _vendor.json.
# shellcheck disable=SC2086
for f in $MANIFEST; do
Comment thread
rubambiza marked this conversation as resolved.
Resolved
if [ ! -f "$SRC/scripts/$f.sh" ]; then
echo "ERROR: missing engine source: $SRC/scripts/$f.sh (nothing copied)" >&2; exit 1
fi
done

mkdir -p "$DEST"
# shellcheck disable=SC2086
for f in $MANIFEST; do
if ! cp "$SRC/scripts/$f.sh" "$DEST/$f.sh"; then
echo "ERROR: copy failed for $f.sh" >&2; exit 1
fi
done

# Provenance stamp: record the SOURCE repo's HEAD sha (not the dest repo's).
if ! SHA=$(git -C "$SRC" rev-parse HEAD 2>/dev/null); then
echo "ERROR: cannot read source HEAD sha from $SRC" >&2; exit 1
fi
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
# word-splitting $MANIFEST into one line per script is intentional
# shellcheck disable=SC2086
if ! FILES_JSON=$(printf '%s\n' $MANIFEST | sed 's/$/.sh/' | jq -R . | jq -s .); then
echo "ERROR: could not build file list" >&2; exit 1
fi
if ! jq -n --arg repo "rossoctl/automation" --arg sha "$SHA" --arg at "$NOW" \
--argjson files "$FILES_JSON" \
'{source_repo:$repo, source_sha:$sha, vendored_at:$at, files:$files}' \
> "$DEST/_vendor.json"; then
echo "ERROR: provenance stamp write failed" >&2; exit 1
fi

echo "Vendored $(echo "$MANIFEST" | wc -w | tr -d ' ') engine scripts to $DEST (source $SHA)"
2 changes: 1 addition & 1 deletion skills/automation-health-dashboard/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Generate a unified executive-facing dashboard combining link-health and dep-bump

## Prerequisites

- `bash` 4+ (macOS ships 3.2; use `brew install bash` for 4+)
- `bash` 3.2+ (works with the macOS system default; no bash-4 features used)
- `gh` (GitHub CLI, authenticated with org access)
- `jq` (JSON processor)

Expand Down
2 changes: 1 addition & 1 deletion skills/dep-bump-fixer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Respond to scanner-created issues (`[dep-bump]` title prefix) with severity-appr

## Prerequisites

- `bash` 4+ (macOS ships 3.2; use `brew install bash` for 4+)
- `bash` 3.2+ (works with the macOS system default; no bash-4 features used)
- `gh` (GitHub CLI, authenticated with org access)
- `jq` (JSON processor)

Expand Down
2 changes: 1 addition & 1 deletion skills/dep-bump-scanner/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Monitor all repositories in a GitHub organization for open Dependabot PRs. Class

## Prerequisites

- `bash` 4+ (macOS ships 3.2; use `brew install bash` for 4+)
- `bash` 3.2+ (works with the macOS system default; no bash-4 features used)
- `gh` (GitHub CLI, authenticated with org access)
- `jq` (JSON processor)

Expand Down
2 changes: 1 addition & 1 deletion skills/link-health-fixer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Re-verify and fix broken links reported by the link-health-scanner. Creates fork

## Prerequisites

- `bash` 4+ (macOS ships 3.2; use `brew install bash` for 4+)
- `bash` 3.2+ (works with the macOS system default; no bash-4 features used)
- `gh` (GitHub CLI, authenticated with fork/PR permissions)
- `jq` (JSON processor)
- `curl` (for external link verification and Wayback Machine)
Expand Down
2 changes: 1 addition & 1 deletion skills/link-health-scanner/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Scan all repositories in a GitHub organization for broken links. Creates GitHub

## Prerequisites

- `bash` 4+ (macOS ships 3.2; use `brew install bash` for 4+)
- `bash` 3.2+ (works with the macOS system default; no bash-4 features used)
- `lychee` >= 0.23.0 (link checker: `brew install lychee`) — the scanner relies on
lychee's default exclusion of URLs inside code blocks; do not pass `--include-verbatim`
- `gh` (GitHub CLI, authenticated with org access)
Expand Down
32 changes: 20 additions & 12 deletions skills/repoman/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,24 @@ to infer state. You write it only by calling the setup writer.

## Where the scripts live

- **Bundled with this skill** (`scripts/org.sh`): the enrolled-set resolver and
The entire engine is **bundled with this plugin** under
`${CLAUDE_PLUGIN_ROOT}/skills/repoman/scripts/` — there is no separate automation
checkout to install or locate. Resolve that directory at runtime via
`${CLAUDE_PLUGIN_ROOT}` and point the orchestrator at it with
`REPOMAN_RUN_BIN="${CLAUDE_PLUGIN_ROOT}/skills/repoman/scripts"` (the existing
run-time override `repoman-run.sh` reads). The scripts are a flat set, so each one
sources its siblings (`program-lib.sh`, `org.sh`, …) from that same directory.

- **Read-state / reconcile helpers** (`org.sh`): the enrolled-set resolver and
`repoman_match_name` (bare-name → enrolled owner lookup). Source these to read
state and reconcile names.
- **In an automation checkout** (not bundled): the writer `repoman-setup.sh`,
the capability gate `repoman-check.sh`, and the requirements parser
`repoman-requirements.sh`. Run these from an automation checkout.
`repoman-setup.sh` and `repoman-check.sh` are **commands** — run them with
`--help` first to see full usage. `repoman-requirements.sh` is **not** a
command: it is a sourced library that exposes the function
- **The writer `repoman-setup.sh`, the capability gate `repoman-check.sh`, and
the orchestrator `repoman-run.sh`** are **commands** — run them from the bundled
scripts dir, `--help` first to see full usage. `repoman-requirements.sh` is
**not** a command: it is a sourced library that exposes the function
`repoman_parse_requirements`. You must **source it, then call the function** —
`source <automation>/scripts/repoman-requirements.sh` then
`repoman_parse_requirements <skill-md>`. Never execute it directly (e.g.
`source "${CLAUDE_PLUGIN_ROOT}/skills/repoman/scripts/repoman-requirements.sh"`
then `repoman_parse_requirements <skill-md>`. Never execute it directly (e.g.
`repoman-requirements.sh <skill-md>`): a direct run does **not** emit the JSON
— once rossoctl/automation#113 lands it fails loud with this same guidance,
and before that it exits 0 with empty output (which, captured and parsed as
Expand Down Expand Up @@ -255,7 +261,7 @@ any other reason, re-prompt with the specific reason the validator gave — do
1. locate that program's `SKILL.md` (via the program→skill-dir map above, e.g.
`skills/github-pr-review/SKILL.md`);
2. **source** the parser library once, then call the function:
`source <automation>/scripts/repoman-requirements.sh` →
`source "${CLAUDE_PLUGIN_ROOT}/skills/repoman/scripts/repoman-requirements.sh"` →
`repoman_parse_requirements <skill-md>` →
`{"pat_scopes":[...],"labels_required":[...],"labels_applied":[...],"programs":[...]}`.
Do **not** execute the script directly — it is a sourced library, not a
Expand Down Expand Up @@ -376,8 +382,10 @@ This keeps the setup/activate/reconcile flows fully usable on their own.
4 features)
- `gh` (GitHub CLI, authenticated with org access) — for org detection/expansion
- `jq` (JSON processor)
- An **automation checkout** on `PATH` or at a known location, for
`repoman-setup.sh`, `repoman-check.sh`, and `repoman-requirements.sh`.
- The RepoMan **engine**, bundled with this plugin at
`${CLAUDE_PLUGIN_ROOT}/skills/repoman/scripts/` (`repoman-setup.sh`,
`repoman-check.sh`, `repoman-run.sh`, `repoman-requirements.sh`, and the
program scanners). No separate checkout is required.

### Requirements (machine-readable)

Expand Down
30 changes: 30 additions & 0 deletions skills/repoman/scripts/_vendor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"source_repo": "rossoctl/automation",
"source_sha": "0311752eba5350c74b8c9650137d3e6da65bd547",
"vendored_at": "2026-10-23T03:46:40Z",
"files": [
"automation-health-dashboard.sh",
"core.sh",
"dep-bump-fixer.sh",
"dep-bump-scanner.sh",
"extract-broken-links.sh",
"fork.sh",
"github-api.sh",
"link-health-fixer.sh",
"link-health-scanner.sh",
"org.sh",
"parse-diff-map.sh",
"pr-review-fixer.sh",
"pr-review-impact.sh",
"pr-review-lib.sh",
"pr-review-scanner.sh",
"program-lib.sh",
"repo-sync.sh",
"repoman-check.sh",
"repoman-index.sh",
"repoman-requirements.sh",
"repoman-run.sh",
"repoman-setup.sh",
"weekly-report.sh"
]
}
Loading
Loading