Agent skill

Page Toolbar

by speakeasy-api in speakeasy-api/gram

Build the control bar (search, filters, sort, view) on dashboard list/collection pages with the unified Page.Toolbar compound component.

AGPL-3.0Auto-check passed

Install Page Toolbar

skills CLI
$ npx skills add speakeasy-api/gram --skill page-toolbar -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install speakeasy-api/gram page-toolbar --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/speakeasy-api/gram.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/page-toolbar .claude/skills/page-toolbar && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
page-toolbar
GitHub stars
272
Token cost
~2.1k tokens
SKILL.md length
578 words
Files
1
Skills in repo
39
Repo updated
First seen
Licence
AGPL-3.0

At a glance

Build the control bar (search, filters, sort, view) on dashboard list/collection pages with the unified Page.Toolbar compound component.

  • SKILL.md covers How to use it, Declaring filters, Bridging to existing query logic and Rules, plus 1 more section
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Page Toolbar is an agent skill from speakeasy-api/gram. Build the control bar (search, filters, sort, view) on dashboard list/collection pages with the unified Page.Toolbar compound component. Activate whenever adding or editing the controls above a list/grid/table on a client/dashboard page — a search box, filter chips/sheet, sort dropdown, grid/table view toggle, result count, or a mode toggle — so the page uses Page.Toolbar instead of hand-rolled controls. Phrases like "add a search/filter to this page", "filter bar", "sort dropdown", "view toggle", or "let users…

Its SKILL.md is about 2.1k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

The repository describes itself as: Securely scale AI usage across your organization. A single stack to Connect, Secure, Observe and Distribute agents, MCPs, and Skills within your company. The licence is AGPL-3.0.

Example prompts

  • “add a search/filter to this page”
  • “filter bar”
  • “sort dropdown”
  • “/page-toolbar”

What it can do on your machine

Read from SKILL.md and the folder at commit ad78247. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are javascript and typescript).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Page Toolbar loads about 2.1k tokens when it runs. Until then it costs about 143 tokens; SKILL.md has 578 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~143
When it runs · the whole SKILL.md, loaded when a task matches
~2.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from speakeasy-api/gram at commit ad78247, republished under its AGPL-3.0 licence (© speakeasy-api). 578 words, ~2,055 tokens.

Download SKILL.mdSave it as .claude/skills/page-toolbar/SKILL.md (or your agent's skills folder).
name
page-toolbar
description
Build the control bar (search, filters, sort, view) on dashboard list/collection pages with the unified `Page.Toolbar` compound component. Activate whenever adding or editing the controls above a list/grid/table on a `client/dashboard` page — a search box, filter chips/sheet, sort dropdown, grid/table view toggle, result count, or a mode toggle — so the page uses `Page.Toolbar` instead of hand-rolled controls. Phrases like "add a search/filter to this page", "filter bar", "sort dropdown", "view toggle", or "let users filter the list" should trigger it.
metadata.relevant_files
client/dashboard/**

Page.Toolbar — the one control bar for list pages

Every dashboard list/collection page (Catalog, MCP, Costs, Agent Sessions, Employees, Risk Events, the Observe pages) puts its search + filters + sort + view controls in a single compound component: Page.Toolbar. Do NOT hand-roll a search <input>, a filter sidebar/popover, a sort <select>, a ViewToggle, or filter chips — compose the toolbar pieces. This keeps every page visually identical (one contained grey bar, uniform 40px controls, full width, search+filters left / sort+view right) and changeable in one place.

How to use it

Import Page from @/components/page-layout and render the toolbar on its own row below the page title/description:

jsx
<Page.Toolbar>
  <Page.Toolbar.Search value={q} onChange={setQ} placeholder="Search…" debounceMs={300} />
  <Page.Toolbar.Filters
    schema={FILTERS} values={values} optionsById={optionsById}
    onChange={setValue} onClear={clearValue} onClearAll={clearAll}
  />
  <Page.Toolbar.SortBy
    value={sort} onChange={setSort}
    options={[{ value: "recent", label: "Recently Added" }]}
    direction={dir} onDirectionChange={setDir}   {/* optional asc/desc toggle */}
  />
  <Page.Toolbar.Count>{count} items</Page.Toolbar.Count>
  <Page.Toolbar.ViewAs value={view} onChange={setView} />
  <Page.Toolbar.Actions>{/* page-specific extras, e.g. a SegmentedControl */}</Page.Toolbar.Actions>
  <Page.Toolbar.Refresh onRefresh={() => void refetch()} isRefreshing={isFetching} />
</Page.Toolbar>

The pieces (all optional, written in any order — the toolbar sorts them):

PieceSideWhat it is
SearchleftDebounced white search box (debounceMs optional, built-in clear button)
FiltersleftFilter chips + "More filters" sheet + "Reset to default"
LeadingleftPage-specific left-aligned extras that narrow or re-cut the collection (e.g. a segmented axis track, a scope selector)
SortByrightSort dropdown, optionally with a built-in asc/desc direction toggle (one bordered box)
CountrightResult-count text
ViewAsrightGrid/table toggle (grid/table only)
ActionsrightPage-specific right-aligned extras
RefreshrightManual refresh button (onRefresh required, isRefreshing optional); spins/disables while refreshing and enforces a ~2s minimum visible spin so a fast/cached refetch doesn't look like a no-op

Layout, height (40px), the grey bar, the search↔filters divider, and the left/right justify-between split are all handled by the component — don't re-create them.

A bar with too many controls for one line composes explicit rows inside the same shell instead of hand-rolling a second bar — each Page.Toolbar.Row takes the same pieces and lays out the same left/right clusters (see the costs page's BreakdownBar):

jsx
<Page.Toolbar>
  <Page.Toolbar.Row>
    <Page.Toolbar.Search value={q} onChange={setQ} />
    <Page.Toolbar.Actions>{axisTrack}</Page.Toolbar.Actions>
  </Page.Toolbar.Row>
  <Page.Toolbar.Row>
    <Page.Toolbar.Leading>{scopeControls}</Page.Toolbar.Leading>
    <Page.Toolbar.Actions>{exportButton}</Page.Toolbar.Actions>
  </Page.Toolbar.Row>
</Page.Toolbar>

Declaring filters

Filters are a pure const schema via defineFilters (from @/components/filters), driven by useFilterState(SCHEMA) (URL-param backed). Kinds: multiselect | select | text | boolean | daterange.

ts
import { defineFilters, useFilterState } from "@/components/filters";

const FILTERS = defineFilters([
  {
    id: "date",
    label: "Date range",
    kind: "daterange",
    pinned: true,
    defaultPreset: "30d",
  },
  { id: "status", label: "Status", kind: "multiselect" },
  { id: "policy", label: "Policy", kind: "select" },
]);

const { values, setValue, clearValue, clearAll } = useFilterState(FILTERS);
  • The schema must be a pure literal (no hooks/fetched data) so FilterValues<typeof FILTERS> can derive the typed value object.
  • pinned dimensions always render a chip (with an "All …" default); others appear only when active and live behind "More filters".
  • Pass dynamic option lists (servers, policies, agents) at render via optionsById (a Record<id, {label,value}[]>) — never bake data into the schema.
  • Reuse existing schemas as references: pages/catalog/catalog-filter-schema.ts, pages/mcp/mcp-filter-schema.ts, and the inline COST_FILTERS/SESSION_FILTERS/EMPLOYEE_FILTERS/RISK_FILTERS/OBSERVE_FILTERS.
Show full SKILL.md (207 more words)Show less

Bridging to existing query logic

useFilterState returns URL-persisted values keyed by dimension id. If the page already has its own query/state shape, bridge the unified values back to it rather than rewiring every consumer (see catalog's toCatalogFilterValues). For pages whose filters already live in the URL (the Observe pages), build a values object from the existing reads and route onChange to the existing setters.

Rules

  • Never hand-roll: a bare <input> search, a sort <select>, a ViewToggle outside the toolbar, or filter chips. Use the pieces.
  • Never set per-control heights — the toolbar enforces a uniform 40px.
  • Two-option mode toggles (Tokens/Cost, an Employees/Unknown scope switch, etc.) go in Page.Toolbar.Actions using the shared SegmentedControl (@/components/ui/segmented-control) — give each option a tooltip. ViewAs is for grid/table only.
  • onClearAll must reset filters in a single setSearchParams/clearAll call. Firing one setter per filter clobbers in react-router (it reads a memoized snapshot, so the last navigate wins) — useFilterState.clearAll already does this correctly.
  • The "Reset to default" button is built into Filters; don't add your own clear button.

Where things live

  • components/ui/toolbar.tsx — Page.Toolbar + all pieces (the only place to change layout/height/styling).
  • components/ui/segmented-control.tsx — shared two-or-more option mode toggle.
  • components/filters/ — filter-schema.ts (defineFilters, types, chipLabel, isDimensionActive), useFilterState.ts, and the chip/sheet/control primitives.

Run aube run -F dashboard type-check after changes.

© speakeasy-api, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/page-toolbar of speakeasy-api/gram.

Open the folder on GitHubat commit ad78247

Compare with similar skills

Page Toolbar next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Page Toolbar compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Page Toolbar this skillspeakeasy-api/gram272—~2.1kAutomated safety check: PassAGPL-3.0
DashboardInsForge/InsForge13k—~2.3kAutomated safety check: PassApache-2.0
Agent Sortaffaan-m/ECC275k1 repos~1.5kAutomated safety check: PassMIT
Live DashboardNousResearch/hermes-agent252k—~2.1kAutomated safety check: PassMIT
Dashboarddavepoon/buildwithclaude3.6k—~930Automated safety check: PassMIT
Live Dashboardnexu-io/open-design100k—~2.1kAutomated safety check: PassApache-2.0

Similar skills

  • Dashboard

    InsForge/InsForge

    A skill your agent uses when contributing to InsForge's shared dashboard package.

    13k GitHub stars~2.3k tokensUpdated 2 days ago
    Frontend & DesignAuto-check passed
  • Agent Sort

    affaan-m/ECC

    Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes.

    275k GitHub starsUsed in 1 repo~1.5k tokens
    Auto-check passed
  • Live Dashboard

    NousResearch/hermes-agent

    Build self-updating dashboards from live sources. An agent skill from NousResearch/hermes-agent.

    252k GitHub stars~2.1k tokensUpdated today
    Auto-check passed
  • Dashboard

    davepoon/buildwithclaude

    View all tracked vulnerabilities and their current status. An agent skill from davepoon/buildwithclaude.

    3.6k GitHub stars~930 tokensUpdated 2 days ago
    Auto-check passed
  • Live Dashboard

    nexu-io/open-design

    Notion-style team dashboard rendered as a Live Artifact. An agent skill from nexu-io/open-design.

    100k GitHub stars~2.1k tokensUpdated today
    Productivity & AutomationAuto-check passed
  • GitHub Dashboard

    nexu-io/open-design

    GitHub repository analytics dashboard — stars, forks, contributors, issues, pull requests, recent activity, and top contributors.

    100k GitHub stars~1.8k tokensUpdated today
    DevelopmentAuto-check passed

More from speakeasy-api/gram

All 39 skills in this repo
  • Gram Playwright CLI

    speakeasy-api/gram

    A skill your agent uses when automating the Gram dashboard in a browser, capturing screenshots, inspecting pages.

    272 GitHub stars~3.4k tokensUpdated today
    Auto-check passed
  • Transactional Email

    speakeasy-api/gram

    A skill your agent uses when adding, changing, restyling, reviewing, validating, or previewing a Gram/Speakeasy transactional email, in Go or in LMX/MJML — a template<name.go, a TemplateKey…

    272 GitHub stars~4.7k tokensUpdated today
    Auto-check passed
  • Admin Shadcn

    speakeasy-api/gram

    A skill your agent uses when adding, changing, or styling UI in client/admin (the Gram admin dashboard) that touches shadcn/ui — a button, dialog, table, sidebar, badge, select, tabs, tooltip, card…

    272 GitHub stars~1k tokensUpdated today
    Auto-check passed
  • A skill your agent uses when adding, editing, reviewing, testing, or locating a reviewed skill distributed with the Platform MCP plugin; triggers include "Platform MCP skill", "platformmcpskills"…

    272 GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Clickhouse

    speakeasy-api/gram

    A skill your agent uses when changing or reviewing Gram ClickHouse schemas, migrations, queries, inserts, access principals, bootstrap SQL, Cloud compatibility, partial migration failures, or…

    272 GitHub stars~3.2k tokensUpdated today
    Auto-check passed
  • Feature Flag

    speakeasy-api/gram

    A skill your agent uses when gating a feature behind a flag, dogfooding or gradually rolling out a change, choosing between productfeatures and PostHog feature flags, adding or checking a product…

    272 GitHub stars~2.6k tokensUpdated today
    Auto-check passed

Questions about Page Toolbar

What does Page Toolbar do?

Build the control bar (search, filters, sort, view) on dashboard list/collection pages with the unified Page.Toolbar compound component. Page Toolbar is an agent skill from speakeasy-api/gram.Toolbar compound component.

How do I install Page Toolbar in Claude Code?

Run `npx skills add speakeasy-api/gram --skill page-toolbar -a claude-code`. Or copy the skill folder (.agents/skills/page-toolbar in speakeasy-api/gram) into .claude/skills/page-toolbar in your project. Claude Code loads it when a task matches its description.

How do I install Page Toolbar in Codex?

Run `npx skills add speakeasy-api/gram --skill page-toolbar -a codex`. Or copy the skill folder (.agents/skills/page-toolbar in speakeasy-api/gram) into .agents/skills/page-toolbar in your project. Codex loads it when a task matches its description.

Can I use Page Toolbar in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add speakeasy-api/gram --skill page-toolbar -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/page-toolbar, .gemini/skills/page-toolbar, .github/skills/page-toolbar and .opencode/skills/page-toolbar in your project.

What does Page Toolbar need to run?

SKILL.md names no scripts, command-line tools or credentials: Page Toolbar is instructions for the agent only.

Does Page Toolbar access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Page Toolbar safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Page Toolbar use?

Page Toolbar is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Page Toolbar use?

About 2.1k tokens (SKILL.md is roughly 8.2k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Page Toolbar?

Skills that share tags, products or a category with Page Toolbar: Dashboard (InsForge/InsForge, 13k stars), Agent Sort (affaan-m/ECC, 275k stars), Live Dashboard (NousResearch/hermes-agent, 252k stars) and Dashboard (davepoon/buildwithclaude, 3.6k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Page Toolbar?

speakeasy-api (a GitHub organization) maintains it in speakeasy-api/gram, which has 272 GitHub stars. The repository holds 39 skills in this directory. The repository was last updated on October 8, 2026.

Source: speakeasy-api/gram on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.