Skip to content
Development
Skill

/port-herdr-integration

Port one Herdr provider integration into Sidecar: read the sync report to see which provider moved, pick the port shape, keep the provider half verbatim and swap the transport half, register the adapter everywhere it has to appear, earn a tier from traces rather than copying

From plugin
sidecar
1.1k19 skills
Install
$ npx -y skills add marcus/sidecar --skill port-herdr-integration --agent claude-code

How it fires

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

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/port-herdr-integration

Context preview

The summary Claude sees to decide when to auto-load this skill.

Port one Herdr provider integration into Sidecar: read the sync report to see which provider moved, pick the port shape, keep the provider half verbatim and swap the transport half, register the adapter everywhere it has to appear, earn a tier from traces rather than copying

SKILL.md

port-herdr-integration.SKILL.md
name: port-herdr-integration
description: >
  Port one Herdr provider integration into Sidecar: read the sync report to see
  which provider moved, pick the port shape, keep the provider half verbatim and
  swap the transport half, register the adapter everywhere it has to appear, earn
  a tier from traces rather than copying Herdr's table, and pass the guards that
  gate every other adapter. Use when adding or re-porting a provider integration
  under internal/agentintegration, when a weekly Herdr sync review shows an asset
  changed, or when a capability entry needs promoting.
user-invocable: false

Porting one Herdr integration

Sidecar installs its own hook, plugin and extension assets into other agents' configuration so those agents report their lifecycle state and their session identity back to Sidecar. The knowledge in those assets comes from Herdr, which ships seventeen of them. A port takes one provider's knowledge, keeps it verbatim, replaces Herdr's transport with Sidecar's, and lands it behind the same guards every existing adapter passes.

This is a procedure. Work through it in order for one provider at a time. Every step names the file to open and the test that gates it.

0. How Sidecar mirrors Herdr

Four things hold the mirror in place. Read them before you write anything.

**The vendored tree.** `internal/agentintegration/upstream/<dir>/` holds byte-for-byte copies of Herdr's `src/integration/assets`. Nothing installs them and no runtime path reads them; they exist so re-porting a provider is a review of a diff rather than a fresh reading. `internal/agentintegration/upstream/herdr-agent-state.test.ts` at the root of that tree is upstream's own test, and its payloads are where your fixtures come from.

**The lock.** `internal/agentintegration/upstream.lock.json` pins every vendored file by SHA-256 and records each provider's `HERDR_INTEGRATION_VERSION`. It is keyed by Herdr's **agent id**, which is not always the directory name: `agy` is the id and `antigravity_cli` is the directory. `TestVendoredIntegrationAssetsMatchLock` fails if a vendored byte changes without a matching lock entry, so never hand-edit anything under `upstream/`.

**The provenance record.** `internal/agentintegration/portedfrom.go` holds one `PortedFrom` row per shipped asset: the Sidecar provider id, the Herdr agent id (`UpstreamID`, which must match the lock's key), the directory, the upstream version the port was written against, the commit, and prose evidence. It is Go data rather than a header comment because several Sidecar assets are Go values with no file to put a header in. `TestEveryAdapterRecordsWhatItWasPortedFrom` fails if an adapter ships without a row.

**The sync tool and the weekly review.** `internal/tools/herdrsync` re-vendors the tree, rewrites the lock, and renders `internal/agentactivity/manifests/report.md`. `.github/workflows/herdr-sync.yml` runs it every Monday, pushes `bot/herdr-sync`, and puts that report into the pull request body.

> **`go run ./internal/tools/herdrsync` performs a real sync.** It fetches from Herdr and overwrites the vendored manifest and integration trees in your working directory. Do not run it to "see what it does". Read `internal/agentactivity/manifests/report.md`, and drive the renderer from tests when you need to see output. Name the package explicitly if you ever must run it, and **never glob `./internal/tools/...`**, which expands to the sync tool and syncs.

1. Read the sync report to see which provider moved

Open `internal/agentactivity/manifests/report.md` and find `## Integration assets`. It has two halves.

The table has one row per vendored provider: `Agent | Asset directory | Version | Previous | Change | Sidecar port`. The `Change` column says `unchanged`, `**bumped**`, `**rolled back**`, `added` or `first sync`. The `Sidecar port` column is derived from `PortedFromRecords()` at render time and reads either `` `<provider>` from version N `` or `not ported`.

Then `### Upstream changes since each Sidecar port` gives, per ported provider, the diff between the upstream bytes at the commit the port was written from and the bytes just vendored. It diffs **bytes, not version numbers**, so a file upstream edited without bumping still shows. A file it could not read says `was **not compared**`; that is a comparison that did not happen and never evidence that anything changed.

Two traps:

  • **The committed `report.md` is a snapshot, not a live view.** It is written only by a real sync run, so between syncs it is as stale as the last run. If it says `not ported` for a provider that has an adapter, believe `PortedFromRecords()` and not the file. `TestARenderedReportNeverCallsAPortedProviderUnported` in `internal/tools/herdrsync/herdrsync_test.go` renders the section against the embedded lock and the real records, so the *next* sync is guaranteed truthful; the committed file catches up when the workflow next runs. Do not regenerate it by hand.
  • Everything below the table is bounded at `integrationDiffSectionBudget` (600 lines) so the report fits GitHub's pull request body limit. A diff elided there is named, not dropped.

The weekly review already surfaces this for you: `internal/agentintegration/upstream` is in the workflow's change-detection paths and in the paths it commits to the sync branch, so a ported provider's asset diff appears twice, as raw file changes on the branch and as rendered diffs in the pull request body.

2. Choose the port shape

There are three, and the choice is decided by where the provider's knowledge lives upstream, not by preference.

Shape A: entry in the provider's config file

Use it when Herdr's knowledge is a table in its Rust rather than in a shipped script: `src/integration/mod.rs` holds `(event, matcher, action)` rows, and the asset upstream ships is a thin shell shim that only gates on `HERDR_ENV` and writes a socket frame. There is nothing in that shim worth porting, because `sidecar agen

Read more
Ships withsidecar

Always check if you are running in Sidecar: run sidecar agents for capabilities. You might never open your editor again. Status: Ready for daily use. Please report any issues you encounter. Documentation · Getting Started · Comprehensive List of Features

Get the whole plugin
Stats
1,075
Stars
82
Forks
Active
Maintenance
Go
Language
MIT
License
5d ago
Last commit
8mo ago
Created

Repo: marcus/sidecar

Other skills on sidecar.