
Research
Shai-Hulud Descends to Hades: Miasma Worm Campaign Spreads with New PyPI Wave
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.
agentbuttons
Advanced tools
Drop-in buttons for every AI coding agent — Claude Code, Hermes, OpenClaw, IronClaw, and more. One import, every agent.
One package. Every AI coding agent.
Drop-in “Run on …” buttons for Claude Code, Cowork, Hermes, OpenClaw, and the rest of the harness ecosystem. Framework-agnostic Web Components, optional React and Vue integrations, and a single entry point for your site or app.
Shared preferences: claudebuttons, hermesbuttons, and clawbuttons each set an agentpreferences cookie (same origin) when a visitor copies a command. agentbuttons exposes <preferred-button> and PreferredButton (React) to render one button for your command, picking the agent the user has used most recently when that agent is listed in your agents attribute; if the cookie is missing, order falls back to your list.
| Agent | Element | Events prefix |
|---|---|---|
| Claude Code | <claude-code-button> | cb- |
| Cowork | <cowork-button> | cb- |
| Hermes Agent | <hermes-button> | hb- |
| Hermes Skills | <hermes-skill-button> | hb- |
| OpenClaw | <openclaw-button> | cb- |
| IronClaw | <ironclaw-button> | cb- |
| NanoClaw | <nanoclaw-button> | cb- |
| ZeroClaw | <zeroclaw-button> | cb- |
| OpenHarness | <openharness-button> | cb- |
| ClaudeClaw | <claudeclaw-button> | cb- |
| Preferred (smart CTA) | <preferred-button> | (delegates to the chosen agent’s events) |
When you import the full package, <hermes-button> is the Hermes Agent control (hb-* events). The OpenClaw-style harness that also targets Hermes is available in React as ClawHermesButton (see Framework integration).
agentpreferences cookie)On the same origin, any copy action from a family button updates the agentpreferences cookie ({ "order": ["hermes", "claude-code", ...] }, most recent first). Use preferred-button (or PreferredButton in React) to show a single CTA:
agents to a comma-separated list of agent ids in your default priority order, e.g. claude-code,hermes,openclaw.order that also appears in agents; if none match, it uses the first id in agents.command, skill-url, theme, variant, size, shape, popup, …) from preferred-button onto the rendered child.<script type="module">
import 'agentbuttons';
</script>
<preferred-button
agents="claude-code,hermes,openclaw"
command="/ship the analytics dashboard"
skill-url="https://example.com/skill.zip"
theme="branded"
variant="filled"
></preferred-button>
The host exposes data-resolved-agent with the winning id (for styling or analytics). You can read or adjust preferences in JS with readAgentPreferences, writeAgentPreferences, and pickPreferredAgentId from agentbuttons.
npm install agentbuttons
CDN (global IIFE):
<script src="https://unpkg.com/agentbuttons@latest/dist/index.global.js"></script>
Note: The single global bundle includes every agent implementation. It is larger than any one agent alone. For production CDN usage without a bundler, you can instead load claudebuttons, hermesbuttons, and clawbuttons as separate
<script>tags. Prefernpm install agentbuttonsand ESM/CJS imports when you want tree-shaking and one coherent version line.
<script type="module">
import 'agentbuttons';
</script>
<claude-code-button command="/deploy --prod" theme="branded"></claude-code-button>
<cowork-button command="/review" skill-url="https://example.com/skill.zip"></cowork-button>
<hermes-button command="/research deep-dive on your API" theme="branded"></hermes-button>
<hermes-skill-button
command="/competitive-analysis"
skill-url="https://example.com/skills/analysis.zip"
></hermes-skill-button>
<openclaw-button command="Ship the dashboard" theme="branded"></openclaw-button>
<ironclaw-button command="Audit dependencies" variant="outline"></ironclaw-button>
document.querySelector('claude-code-button')
?.addEventListener('cb-copy', (e) => console.log('Copied:', e.detail.command));
document.querySelector('hermes-button')
?.addEventListener('hb-copy', (e) => console.log('Copied:', e.detail.command));
Dedicated wrappers handle SSR, hydration, and prop forwarding ('use client' where needed):
import {
ClaudeCodeButton,
CoworkButton,
HermesButton,
HermesSkillButton,
OpenClawButton,
ClawHermesButton,
IronClawButton,
NanoClawButton,
ZeroClawButton,
OpenHarnessButton,
ClaudeClawButton,
PreferredButton,
} from 'agentbuttons/react';
function App() {
return (
<>
<PreferredButton
agents="claude-code,hermes,openclaw"
command="/my-skill"
skillUrl="https://example.com/skill.zip"
theme="branded"
/>
<ClaudeCodeButton command="/my-skill" theme="branded" onCopy={(cmd) => console.log(cmd)} />
<HermesButton command="/weekly-standup" theme="branded" onHbCopy={(e) => console.log(e.detail.command)} />
<OpenClawButton command="Deploy the app" theme="branded" />
</>
);
}
Use ClawHermesButton when you need the OpenClaw-harness Hermes variant alongside HermesButton (Hermes Agent).
import { createApp } from 'vue';
import { AgentButtonsPlugin } from 'agentbuttons/vue';
import App from './App.vue';
const app = createApp(App);
app.use(AgentButtonsPlugin);
app.mount('#app');
<template>
<preferred-button
agents="claude-code,hermes,openclaw"
command="/my-skill"
skill-url="https://example.com/skill.zip"
theme="branded"
/>
<claude-code-button command="/my-skill" theme="branded" @cb-copy="onCopy" />
<hermes-button command="/standup" theme="branded" @hb-copy="onHermesCopy" />
<openclaw-button command="/deploy" theme="branded" @cb-copy="onCopy" />
</template>
The package also re-exports ClaudeButtonsPlugin, HermesButtonsPlugin, and ClawButtonsPlugin if you only need a subset.
Use standard custom element patterns: import 'agentbuttons' (or the scoped package you need), declare unknown tags in your compiler config where required, and listen for cb-* / hb-* events on the host elements.
| Theme | Role |
|---|---|
branded | Primary brand look (default) — exact colors depend on the agent (e.g. Claude terracotta, Hermes violet, OpenClaw red). |
branded-alt | Secondary accent palette where supported. |
dark | Dark surface, light text, agent-colored accents. |
light | Light surface, dark text, agent-colored accents. |
system | Follows prefers-color-scheme between light and dark. |
| Size | Typical height |
|---|---|
sm | 2rem (~32px at default root font size) |
md | 2.5rem (~40px) (default) |
lg | 3rem (~48px) |
Sizes use rem and respect user font preferences.
| Variant | Description |
|---|---|
filled | Solid fill (default) |
outline | Border emphasis, transparent fill |
ghost | Minimal chrome |
| Shape | Description |
|---|---|
rounded | Default corner radius (default) |
pill | Fully rounded ends |
square | Sharper corners |
All buttons dispatch native CustomEvents with bubbles: true and composed: true (they cross Shadow DOM).
cb-* (Claude Code, Cowork, OpenClaw-style harnesses)| Event | Detail | Fired when |
|---|---|---|
cb-copy | { command: string } on Claude Code / Cowork; { command: string, harness: string } on harness buttons | Command copied to clipboard |
cb-open | { command: string } or { command, fullCommand?, harness } | Primary action / popup opens |
cb-close | — on Claude Code / Cowork; { harness: string } on harness buttons | Popup closed |
cb-download | { url: string } | Skill package downloaded (Cowork; Hermes Skills uses hb-download below) |
hb-* (Hermes Agent & Hermes Skills)| Event | Detail | Fired when |
|---|---|---|
hb-copy | { command: string } | Command copied to clipboard |
hb-open | { command: string } | Button clicked / popup opens |
hb-close | — | Popup closed |
hb-download | { url: string } | Skill package downloaded (Hermes Skills only) |
import {
createClaudeCodeButton,
createCoworkButton,
createHermesButton,
createHermesSkillButton,
createClawButton,
} from 'agentbuttons';
const claude = createClaudeCodeButton({
command: '/deploy --prod',
theme: 'branded',
onCopy: (cmd) => console.log('Copied:', cmd),
});
const openClaw = createClawButton('openclaw', {
command: 'Run the migration',
theme: 'branded',
});
document.getElementById('host')?.append(claude, openClaw);
createClawButton accepts a harness id: 'openclaw' | 'hermes' | 'ironclaw' | 'nanoclaw' | 'zeroclaw' | 'openharness' | 'claudeclaw'.
import { injectAllStructuredData } from 'agentbuttons';
injectAllStructuredData();
Scans the document for agent buttons and injects appropriate structured data helpers for discovery and rich results.
Registration normally runs when you import the package. For apps that need controlled timing:
import { register } from 'agentbuttons';
register();
Works wherever Custom Elements v1 is available:
| Browser | Minimum version |
|---|---|
| Chrome | 67+ |
| Firefox | 63+ |
| Safari | 10.1+ |
| Edge | 79+ |
agentbuttons bundles and re-exports claudebuttons, hermesbuttons, and clawbuttons. Each npm page lists the canonical source repository when published.
MIT
FAQs
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.

Security News
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.