Skip to content
Development
Command

/sync-ecosystem

Detect API changes, sync satellite repos, and publish releases

BOOST
From plugin
forgedock
11980 skills80 commands
Install
> /plugin marketplace add RapierCraftStudios/ForgeDock
> /plugin install forgedock@forgedock

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/sync-ecosystem

Context preview

What this command does when you run it.

Detect API changes, sync satellite repos, and publish releases

Command definition

sync-ecosystem.md
description: Detect API changes, sync satellite repos, and publish releases
argument-hint: "[check | auto | status | publish | PR-number]"
install: extras

<!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios --> <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->

/sync-ecosystem — Cross-Project Sync & Publish

> **Skill names**: `{FORGE_SKILL_PREFIX}` is `forgedock:` (plugin install) or empty (`install.sh`), resolved once per run by `commands/work-on.md` § Skill Name Resolution. If the skill is not found under either name, STOP and report "skill not found" — never run the phase inline.

**Input**: $ARGUMENTS

When the `{project.name}` API surface changes (new parameters, endpoints, modes, pricing), satellite projects need updates. This command detects what changed, creates tracking issues, checks publication status, and publishes releases.

---

Config Preamble

Before any phase runs, build the ecosystem registry from `forge.yaml → repos.satellites`.

# Read satellite repos from forge.yaml
# Each entry provides: prefix, repo, staging_branch, local_path
# (Optional: package, publish_workflow — read from each satellite's package.json / workflow files)
CONFIG_FILE="${FORGE_CONFIG:-forge.yaml}"

# Gate: if repos section is absent or has no satellites, stop here
if [ -z "$(yq '.repos.satellites // empty' "$CONFIG_FILE" 2>/dev/null)" ]; then
  echo "No satellite repos configured in forge.yaml → repos.satellites."
  echo "Add entries to forge.yaml to use /sync-ecosystem:"
  echo ""
  echo "  repos:"
  echo "    satellites:"
  echo "      - prefix: \"sdk\""
  echo "        repo: \"your-org/your-sdk\""
  echo "        staging_branch: \"main\""
  echo "        local_path: \"/home/youruser/projects/your-sdk\""
  exit 0
fi

# For each satellite entry, resolve template variables:
#   {COMPONENT}        = prefix (e.g. "mcp", "sdk", "n8n")
#   {GH_REPO}          = repo   (e.g. "your-org/your-mcp-server")
#   {REPO_PATH}        = local_path  (e.g. "/home/youruser/projects/your-mcp-server")
#   {STAGING_BRANCH}   = staging_branch (e.g. "main")
#   {PACKAGE}          = read from {REPO_PATH}/package.json "name" field (npm)
#                        or {REPO_PATH}/pyproject.toml "name" field (PyPI)
#   {PUBLISH_WORKFLOW} = read from {REPO_PATH}/.github/workflows/ — the workflow
#                        triggered by GitHub Release (look for "on: release:")

# For monorepo satellites (multiple packages in one repo):
#   Use a subpath qualifier in local_path, e.g.:
#     local_path: "/home/youruser/projects/myproject"
#     subpaths:
#       python_sdk: "sdk/python"
#       node_sdk: "sdk/node"
#   Then {REPO_PATH}/sdk/python and {REPO_PATH}/sdk/node are the per-SDK roots.

PROJECT_NAME=$(yq '.project.name' "$CONFIG_FILE")
PROJECT_BOARD_OWNER=$(yq '.project_board.owner // .project.owner' "$CONFIG_FILE")
PROJECT_BOARD_NUMBER=$(yq '.project_board.project_number // empty' "$CONFIG_FILE")
PROJECT_BOARD_ID=$(yq '.project_board.project_id // empty' "$CONFIG_FILE")

---

Ecosystem Registry

Satellite Projects

Build the ecosystem registry from `forge.yaml → repos.satellites`. Each entry in the `satellites` array becomes one row in the registry:

| Field in `forge.yaml` | Maps to | |-----------------------|---------| | `satellites[].prefix` | `{COMPONENT}` — the short identifier used in issue routing (e.g. `mcp:5`) | | `satellites[].repo` | `{GH_REPO}` — full `owner/repo` used in all `gh` commands | | `satellites[].local_path` | `{REPO_PATH}` — absolute local path used in all `cd` commands | | `satellites[].staging_branch` | `{STAGING_BRANCH}` — PR target branch for this satellite | | Read from `{REPO_PATH}/package.json` | `{PACKAGE}` — npm package name | | Read from `{REPO_PATH}/.github/workflows/` | `{PUBLISH_WORKFLOW}` — workflow file triggered on release |

**Example registry output** (what the agent constructs from your `forge.yaml`):

Component: {COMPONENT}
  Repo:             {GH_REPO}
  Local path:       {REPO_PATH}
  Package:          {PACKAGE} ({REGISTRY: npm or PyPI})
  Publish trigger:  GitHub Release → {PUBLISH_WORKFLOW}

Iterate over all `repos.satellites` entries before proceeding to Phase 1.

Version Bump Rules

  • **Satellite repos** (separate GitHub repos): Version lives in `package.json`. Must be bumped, committed, and pushed to `main` BEFORE creating the GitHub Release tag. The release tag must match the version (`v{VERSION}`).
  • **Monorepo packages** (SDKs or tools inside a single repo): Version lives in `pyproject.toml` / `package.json` in the monorepo. Must be bumped, committed, and pushed to `main` BEFORE triggering the publish workflow.

---

Command Router

| Input | Action | |-------|--------| | `check` or empty | Scan recent PRs for API changes, report what needs syncing | | `auto` | Same as check, but auto-create issues in satellite repos | | `status` | Check publication status of ALL ecosystem components (code vs published versions) | | `publish` | Bump versions, cut releases, and trigger publishes for all components with unpublished changes | | `publish {COMPONENT}` | Publish a specific component by prefix | | `PR-number` (e.g., `#1500`) | Analyze a specific PR for ecosystem impact |

---

Phase 1: Detect API Surface Changes

**Skip this phase if input is `status` or `publish`.**

If input is a PR number:

# Get the PR diff
gh pr diff {PR_NUMBER} --name-only
gh pr view {PR_NUMBER} --json title,body,files

If input is `check` or `auto`:

# Find recent merged PRs to staging or main (last 7 days)
gh pr list --state merged --base {branches.staging} --limit 20 --json number,title,mergedAt,files
gh pr list --state merged --base {branches.default} --limit 10 --json number,title,mergedAt,files

Analyze changes for sync triggers

Scan the changed files for API surface modifications. The file patterns below are illustrative — adapt to your project's structure:

| File Pattern | Trigger Type | Satellite I

Read more
Ships withforgedock

ForgeDock — autonomous AI dev pipeline for Claude Code. GitHub as agent memory: issue in, PR out.

Get the whole plugin

Other commands on forgedock.