agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…
ACTIVATE when creating storybook stories, reviewing PRs with .stories.tsx files, or planning Storybook-related work with rpi:* skills.
$ npx -y skills add humanlayer/humanlayer --skill storybook --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/storybookContext preview
The summary Claude sees to decide when to auto-load this skill.
ACTIVATE when creating storybook stories, reviewing PRs with .stories.tsx files, or planning Storybook-related work with rpi:* skills.
name: storybook description: | ACTIVATE when creating storybook stories, reviewing PRs with .stories.tsx files, or planning Storybook-related work with rpi:* skills.
This skill defines the three-tier component taxonomy for Storybook stories and the patterns to follow.
| Type | Definition | In Storybook? | |------|------------|---------------| | **Pure** | Stateless or low-state production component with no app stores, queries, routing, or providers | Yes — default | | **ShellDemo** | Storybook-only wrapper that composes real components to demonstrate interactivity, layouts, or state | Yes — sparingly | | **Wired** | Production component connected to business logic, hotkeys, stores, queries | No |
`Wired*` is the only prefix for connected production components. `Connected*` is retired repo-wide. A Wired component owns queries, stores, routing, hotkeys, and business logic, then composes Pure shells and leaves. Storybook interaction wrappers are always named `*ShellDemo`, never `Wired*`.
Avoid prop-forwarding pure intermediates. A Pure layout component exposes literal `children`; the Wired layer fills those slots with Wired leaves, and each Wired leaf renders its Pure leaf with a flat, one-hop interface. The canonical production/story pairs are:
Stories use the same Pure shells as production and fill their slots with Pure leaves. They are provider-free. Never render or wrap a Wired component in a story.
Pure composition has one seam: literal `children`. Do not add named `ReactNode` props, component props, or render props for Storybook convenience. When a shell must associate caller content with its own layout records, use keyed children, following `ArtifactCommentPanel`.
**Mock-up** — defines fake inline UI instead of importing real production components. These create noise and mislead developers about what's real vs. prototype. DELETE mock-ups; do not convert them.
**Smell test:** The story file defines JSX/markup inline instead of importing a component from a production path like `../components/` or `@humanlayer/ui`.
The preferred form. Import the real Pure component and pass static data via `args`.
// packages/ui/src/components/session-label-badge.stories.tsx
import type { Meta, StoryObj } from "@storybook/react"
import { SessionLabelBadge } from "./session-label-badge"
const meta = {
title: "Components/SessionLabelBadge",
component: SessionLabelBadge,
} satisfies Meta<typeof SessionLabelBadge>
export default meta
type Story = StoryObj<typeof meta>
export const Default: Story = {
args: { label: "bug-fix", color: "blue" },
}For Pure components needing demo-only interactivity (dialogs, toggles), define a small provider-free `*ShellDemo` inside the `.stories.tsx`. The ShellDemo owns local state; the real Pure component is imported from production.
// packages/ui/src/components/bypass-permissions-dialog.stories.tsx
const BypassPermissionsDialogShellDemo = ({ sessionCount }: { sessionCount?: number }) => {
const [open, setOpen] = useState(false)
return (
<>
<Button onClick={() => setOpen(true)}>Open Bypass Dialog</Button>
<BypassPermissionsDialog
open={open}
onOpenChange={setOpen}
onConfirm={(minutes) => console.log("Confirmed with timeout:", minutes)}
sessionCount={sessionCount}
/>
</>
)
}
export const Default: Story = {
render: () => <BypassPermissionsDialogShellDemo />,
}When a ShellDemo needs significant local state or composes multiple real Pure components, put it in `storybook/*.tsx`. Keep the `.stories.tsx` thin. ShellDemos remain provider-free; if a component requires app providers, story the Pure shells and leaves below that boundary instead.
// storybook/session-table.tsx — ShellDemo companion
export const SessionTableShellDemo: FC<SessionTableShellDemoProps> = (props) => {
const [selectedId, setSelectedId] = useState<string>()
return <SessionTable {...props} selectedId={selectedId} onSelect={setSelectedId} />
}
// storybook/session-table.stories.tsx — thin
const meta: Meta<typeof SessionTableShellDemo> = {
title: "Shell Demos/SessionTable",
component: SessionTableShellDemo,
}
export const Default: Story = { args: {} }For demonstrating page layouts or how multiple real components sit together. Use sparingly.
import { SidebarShell, TaskRow } from "@humanlayer/ui"
export const WithTask: Story = {
render: () => (
<SidebarShell>
<ul><TaskRow {...taskRowProps}>Pure session rows go here</TaskRow></ul>
</SidebarShell>
),
}`KanbanBoard.stories.tsx`, the sidebar stories, and the artifact-comment-panel stories are the canonical slot-composition examples. Their shells are production components, their slot contents are Pure leaves, and none requires an app provider.
All ShellDemos must use the `Shell Demos/` top-level nav group prefix in their `title` to visually separate them from Pure component stories:
const meta = {
title: "Shell Demos/SessionTable", // NOT "Components/SessionTable"
component: SessionTableDemo,
}Before creating or approving a story:
1. Does the story import a real production component? If no → DELETE or fix 2. Does the story render only Pure components and stay provider-free? If no → move down to the Pure boundary 3. Does composition use only literal `ch
HumanLayer runs coding agents (Claude Code, Codex, OpenCode, Pi) on your machines and lets your team steer them from one place: tasks, sessions, plans, and reviews, synced between a desktop app, a web app, and a daemon on each host. This repo holds all of it.
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…
Rewrites ambiguous English into ASD-STE100 style — one meaning per word, active voice, simple tense, short sentences. Use when…
Use for 1) inspecting PR state, 2) reading review threads, or 3) debugging CI failures. Otherwise use the gh CLI.
Bump the base version of one or more packages (riptide-native, cli, linear-cli, rpi-plugin) on a PR - updates every synced file,…
Diff call stacks across git commits for agentic code review (22 languages). Run `calldiff --help` for usage details.
Use this to skill to write shell scripts or run shell commands to automate tasks in the browser or otherwise use Chrome DevTools…