Skip to content

feat(skill): install the brevo-cli skill for Codex and Gemini CLI too - #138

Open
piyushsarin-sib wants to merge 10 commits into
mainfrom
feat/skill-install-any-agent
Open

piyushsarin-sib wants to merge 10 commits into
mainfrom
feat/skill-install-any-agent

Conversation

@piyushsarin-sib

@piyushsarin-sib piyushsarin-sib commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

What changed

brevo skill:cli install installed the agent skill for Claude Code only, and the skill told every other agent not to install it. The skill follows the open Agent Skills format, which Codex and Gemini CLI load too, so this PR lets the CLI install it for them.

brevo skill:cli install                      # Claude Code: ~/.claude/skills/brevo-cli/ (unchanged default)
brevo skill:cli install --agent codex,gemini # ~/.agents/skills/brevo-cli/
brevo skill:cli install --agent all          # both
  • One copy for Codex and Gemini CLI. Codex reads ~/.agents/skills/ (docs). Gemini CLI reads the same directory as an alias of ~/.gemini/skills/ and gives it precedence (docs). --agent codex,gemini therefore writes a single copy.
  • uninstall removes every copy the CLI installed, for any agent, or only the agents given with --agent. It still deletes only directories carrying the .brevo-skill.json marker.
  • Auto-refresh now keeps every installed copy current, not only the Claude Code one.
  • BREVO_AGENTS_HOME overrides ~/.agents/, the same way BREVO_CLAUDE_HOME overrides ~/.claude/.
  • --json: install and uninstall results gain an agents field naming the agents that read path. This only adds a field.
  • Unknown agents (--agent cursor) are refused with the list of valid values, before anything is written.

Docs, kept in sync

agent-context/SKILL.md, agent-context/AGENTS.md, the README (env var table and the agent integration section) and CLAUDE.md no longer describe the skill as Claude-only.

  • AGENTS.md now branches by whether the agent loads skills from a directory, rather than Claude versus other agents.
  • Agents that don't load skills (Claude Desktop chat, Copilot CLI) are still pointed to AGENTS.md.
  • CLAUDE.md asks to keep the skill's wording agent-neutral.

Unrelated note: the README mentions a one-time skill-install banner (~/.brevo/skill-banner.json), but I couldn't find it in src/ on main. It's left untouched here.

Behaviour that doesn't change

brevo skill:cli install without --agent installs exactly as before (Claude Code only). Existing installs keep their marker and keep auto-refreshing.

Checks

  • Unit tests: parseSkillAgents, getAgentsSkillsRoot, installing into ~/.agents, all agents, isInstalled, uninstall per agent and for all agents, auto-refresh of an ~/.agents copy, and the command-level --agent handling. 1790 tests pass.
  • yarn lint and yarn build pass.
  • Ran the built CLI: brevo skill:cli install --agent all --json writes both copies.
  • Changeset added (minor: a new flag and a new env var)

🤖 Generated with Claude Code

Also in this PR: install from the brevo-skills catalog (from #140)

The brevo skill command group replaces the one-skill skill:cli group. Skills come from the brevo-skills catalog instead of only the copy bundled with the CLI.

brevo skill install [names...]    # every skill when none is named; `default` skills always included
brevo skill update [names...]
brevo skill uninstall [names...]
brevo skill list
brevo skill check                 # exit 1 when a skill is outdated or modified on disk
  • Flags: --agent claude,codex,gemini|all, --pin <release>, --mcp (registers the Brevo MCP server through each agent CLI, or prints the command), --force, --dry-run, --json.
  • Integrity: each skill's files are fetched from the release tag and hashed against the catalog before anything is written. A mismatch skips that skill and the command exits 1.
  • Path safety: catalog paths must be plain /-joined segments (no .., backslash, drive letter or symlink on the way); an unsafe path skips the skill and exits 1. --mcp spawns the agent CLI by absolute path with no shell; on Windows only an .exe runs, a .cmd/.bat launcher is printed instead.
  • Skips: a skill whose min_cli_version is newer than the CLI, or whose platforms exclude the agent, is skipped with a message.
  • State: each installed directory has .brevo-skill.json; ~/.brevo/skills.lock.json records versions, releases and pins; the catalog is cached at ~/.brevo/skills-catalog.json.
  • Update hint: after any command, if the cache is older than 12 hours, one stderr line names outdated unpinned skills. BREVO_SKILL_AUTOREFRESH=1 reinstalls them instead. Silent on network failure.
  • Offline: brevo skill install brevo-cli installs the bundled copy.
  • Env: BREVO_SKILLS_CATALOG_URL, BREVO_SKILLS_FILES_URL.
  • Compatibility: skill:cli install|uninstall stay as hidden aliases. --json results now carry status (installed, updated, already-installed, skipped with reason; removed, not-installed).

Depends on getbrevo/brevo-skills being public. The catalog is read from that repo's release assets (releases/latest/download/catalog.json) and files from raw.githubusercontent.com, so these commands only work for users once it is public and has a release.

Also in this PR: brevo-skills sync trigger (was #139)

After a release publishes @getbrevo/cli, release.yaml dispatches sync-skill in getbrevo/brevo-skills for brevo-cli at the release commit. That repo opens a PR for review, so nothing reaches users without a merge there. Best-effort: continue-on-error, and without the token it only warns.

Also runnable by hand, and Homebrew is its own job.

  • The brevo-skills sync is a composite action (.github/actions/sync-brevo-skills) used by the Release job and by a new manual workflow: Actions → Sync brevo-skills → Run workflow (optional ref, defaults to the tip of main; fails loudly if the token is missing).
  • The Homebrew formula bump moves out of the publish job into .github/workflows/bump-homebrew.yml, which Release calls as a separate homebrew job after a publish. The same workflow has a Run workflow button (optional version, defaults to the latest on npm; validated before use). A failed bump no longer fails the release job and can be re-run alone.
  • Both manual workflows run in the npm-publish environment, so they need the same reviewer approval as a release and only run from main. The homebrew job asks for its own approval after the publish, since it uses that environment's HOMEBREW_TAP_TOKEN.
  • The manual workflows only show up in the Actions tab once they are on main.

Before this step can run:

  • Add secret BREVO_SKILLS_SYNC_TOKEN to the npm-publish environment (fine-grained token or GitHub App token, actions: write on getbrevo/brevo-skills only)
  • sync-skill.yml is on getbrevo/brevo-skills default branch (it is)

Also drops the internal ticket keys from agent-context/ (the public skill text).

`brevo skill:cli install --agent <claude|codex|gemini|all>` installs the
skill into each agent's skills directory: ~/.claude/skills for Claude Code
(the default, unchanged), ~/.agents/skills for Codex and Gemini CLI, which
both read it, so one copy serves the two.

- uninstall removes every copy the CLI installed, or one agent's with --agent
- auto-refresh keeps every installed copy current
- BREVO_AGENTS_HOME overrides ~/.agents, like BREVO_CLAUDE_HOME
- --json results gain an `agents` field
- SKILL.md, AGENTS.md, README and CLAUDE.md no longer call the skill
  Claude-only: it follows the open Agent Skills format these agents load

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…atalog (#140)

* feat(skill): install, update and check skills from the brevo-skills catalog

Replace the one-skill `skill:cli` group with `brevo skill install|update|
uninstall|list|check`. Skills come from the brevo-skills catalog (latest
release asset, or `--pin <release>`), are fetched from the release tag and
hashed by the catalog's contract before they are written; a mismatch skips
that skill and exits 1. Skills marked `default` are always included, platform
fit and `min_cli_version` are honoured, `--mcp` registers the Brevo MCP server
through each agent's own CLI, `--dry-run` writes nothing.

Each installed directory carries `.brevo-skill.json`; `~/.brevo/skills.lock.json`
records versions, releases and pins. The catalog is cached at
`~/.brevo/skills-catalog.json`; after any command, when the cache is older than
12 hours and something is installed, outdated unpinned skills are reinstalled,
silently on network failure. Offline, `skill install brevo-cli` installs the
bundled copy. `skill:cli install|uninstall` stay as hidden aliases.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(skill): describe the skill command group in the README and agent docs

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(skill): refuse unsafe catalog paths and spawn agent CLIs by absolute path

Catalog file and skill paths are validated as `/`-joined plain segments
(letters, digits, dot, underscore, dash; never `.`, `..`, an empty segment,
a backslash, a drive letter, a control character or the marker name), and
the write site checks again: the resolved destination must stay under the
skill directory and no component between the two may be a symbolic link.
A refused file skips that skill, like a hash mismatch, and the run exits 1.

`--mcp` resolves the agent CLI to an absolute path from absolute PATH
entries only and spawns that path with no shell, so the OS performs no
lookup of its own. On Windows only an `.exe` is run; a `.cmd`/`.bat`
launcher needs a shell, so its command is printed instead.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* feat(skill): print an update notice after commands instead of reinstalling skills

After a brevo command, an installed skill that is behind the catalog is now
named in one stderr line pointing to `brevo skill update`; nothing on disk
changes. BREVO_SKILL_AUTOREFRESH=1 restores the reinstall, and
BREVO_NO_SKILL_AUTOREFRESH=1 still turns the check off. The offline bundled
copy follows the same rule.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(skill): call validateSkill through an arrow in map (Sonar S7727)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
shubham773
shubham773 previously approved these changes Oct 15, 2026
CI sets CI=true, which makes the auto-refresh skip itself, so the tests now
start from an environment without that gate. The PATHEXT test names its file
with the upper-case extension so it also matches on a case-sensitive filesystem.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
piyushsarin-sib and others added 2 commits October 16, 2026 10:49
Remove the ASSUMPTION caveats that named internal tickets from
agent-context/SKILL.md and agent-context/AGENTS.md.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
After a release publishes, dispatch getbrevo/brevo-skills' sync-skill
workflow for brevo-cli at the release commit. That repo packages
agent-context/SKILL.md for every agent platform and opens a PR there for
review. Best-effort: skipped with a warning without
BREVO_SKILLS_SYNC_TOKEN, and continue-on-error so it never fails a release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
piyushsarin-sib and others added 5 commits October 16, 2026 14:24
Resolve conflicts with the public-apps GA docs (#143): keep the
`brevo skill update` wording in CLAUDE.md, keep the ticket-free M2M
lines in SKILL.md, and take main's new status/submit/withdraw entries.
Drop the internal ticket keys that main reintroduced into agent-context/.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ill:cli

When the catalog cannot be fetched, `brevo skill install` now says the
brevo-skills repository is not reachable and points to the hidden
`brevo skill:cli install` group, which installs only the CLI skill from
the copy bundled with the CLI.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… hand

Move both post-publish steps into composite actions so the Release job and
two new workflow_dispatch workflows (Sync brevo-skills, Bump Homebrew
formula) run the same code. The release path keeps its behaviour and order
(sync best-effort, Homebrew last, no extra approval); the manual workflows
run in the npm-publish environment, so they need the same reviewer approval
and only run from main. The Homebrew version is now validated before it is
used in a URL, branch name and sed expression.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Resolve the README env var table: keep this PR's new rows in main's
prettier-aligned layout.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
bump-homebrew.yml is now the single implementation: workflow_dispatch for a
manual run, workflow_call for the Release workflow, which runs it as a
separate job after a publish instead of a final step in the publish job. A
failed bump no longer fails the release job and can be re-run alone. Drops
the composite action and the netrc workaround that only the in-job step
needed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants