npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@aphrody/m3-ai

v3.3.7

Published

Material Design 3 agent-interaction components (tool calls, markdown, chat composer, workers, tasks): the SpaceUI (@spacedrive/ai) set rebuilt on @aphrody/m3-primitives.

Readme

@aphrody/m3-ai

Material Design 3 components for agent interfaces: tool-call cards, markdown, chat bubbles, the chat composer, model selector, worker and branch cards, and the task board. They are the SpaceUI @spacedrive/ai set, rebuilt on @aphrody/m3-primitives, the M3 color roles, typescale, shapes and motion of Aphrody OS, and Material Symbols icons.

Install

bun add @aphrody/m3-ai @aphrody/m3-primitives @aphrody/m3-motion

Peers: react and react-dom 18 or 19, tailwindcss 4.1+.

CSS setup

The components ship Tailwind class names that use the M3 utilities of @aphrody/m3-theme. Import the tokens, a palette sheet and the M3 utilities, then let Tailwind scan the package output. The full recipe is in docs/design/SPACEUI-M3-FUSION.md, section "Integration":

@import "tailwindcss";
@import "@aphrody/m3-tokens/m3-tokens.css";
@import "@aphrody/m3-theme/spaceui.css";
@import "@aphrody/m3-theme/tailwind.css";

@source "../node_modules/@aphrody/m3-primitives/dist";
@source "../node_modules/@aphrody/m3-ai/dist";

Register the Material Symbols font once, for example with ensureMaterialSymbols() from @aphrody/material-web/icon/material-symbols.js.

Usage

import { ChatComposer, MessageBubble, ToolCall } from "@aphrody/m3-ai";
import type { ToolCallPair } from "@aphrody/m3-ai";

const pair: ToolCallPair = {
  id: "1",
  name: "file_read",
  argsRaw: '{"path":"README.md"}',
  args: { path: "README.md" },
  resultRaw: '{"text":"# Aphrody"}',
  result: { text: "# Aphrody" },
  status: "completed",
};

export function Conversation({ draft, setDraft, send }: Props) {
  return (
    <>
      <MessageBubble content="List the files" isUser />
      <ToolCall pair={pair} />
      <MessageBubble content="There is one file: `README.md`." isUser={false} />
      <ChatComposer draft={draft} onDraftChange={setDraft} onSend={send} />
    </>
  );
}

Components

| Component | M3 anatomy | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | ToolCall | Outlined card (surface-container-low, medium shape): status icon or circular indicator, text-label-large tool name, expandable arguments and result blocks in font-code on surface-container-highest, error results on error-container. | | Markdown | Prose on the M3 typescale (headline / title / body), font-code code blocks, primary links, outline-variant quotes and tables. size picks the body scale; allowHtml enables raw HTML for trusted content. | | MessageBubble | User turn as a secondary-container bubble (large shape), assistant turn as markdown on the surface with a standard copy icon button. | | ChatComposer | Search-bar anatomy: surface-container-high, extra-large shape, text-body-large input, project pill, model chip, standard mic icon button, filled send / stop icon button. | | ModelSelector | Pill trigger opening an M3 menu (surface-container, extra-small shape, level 2): search field, provider section headers, 48 dp items, selection on secondary-container, capability chips. ModelOptionList and groupModelsByProvider expose the list alone. | | InlineWorkerCard | Filled card (surface-container, medium shape), text-title-small header, status chip, circular indicator while running, expandable transcript of ToolCalls and markdown. | | InlineBranchCard | Filled card for a thinking branch: indicator or branch icon, status chip, expandable conclusion. | | TaskStatusIcon | Material Symbol per status: done success, in progress and ready primary, pending approval warning, backlog outline. | | TaskPriorityIcon | Material Symbol per priority: critical error, high warning, medium primary, low outline. | | TaskRow | Dense M3 list item (48 dp): text-body-large headline, text-body-small supporting columns, 8 % hover state layer, secondary-container selection, overflow menu. | | TaskList | Tasks grouped by status: collapsible text-title-small section headers, outline-variant dividers. | | TaskDetail | Task on an M3 surface: text-headline-small title, property grid, subtasks as a checkbox list, markdown description, filled and text buttons. | | TaskCreateForm | Title and description text fields, priority select, filled Create and text Cancel buttons. |

Helpers from types.ts: pairTranscriptSteps, tryParseJson, isErrorResult, TASK_STATUS_ORDER, TASK_STATUS_LABEL, TASK_PRIORITY_LABEL, and the transcript, task and model types.

Local chat

Everything a chat over an OpenAI-compatible server (llama-server, vLLM, the Aphrody gateway) needs, with no visible string hard-coded:

| Export | Role | | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ChatLabels, chatLabelsFr / chatLabelsEn / chatLabelsJa, resolveChatLabels, formatLabel | One dictionary for every visible string and aria-label. Every chat component takes labels?: Partial<ChatLabels>; missing keys fall back on English. | | streamChatCompletion, createSseParser, parseChatCompletionChunk, chatReducer, ChatStreamError | Pure streaming client of POST <baseUrl>/chat/completions (stream: true): SSE framing, content / reasoning_content / tool-call deltas, finish_reason, top-level citations and refusal. Network failures and 404/502/503/504 are unavailable. | | useOpenAIChat({ baseUrl, model, fetch?, headers?, initialMessages?, preamble?, body? }) | React hook: { messages, send, stop, status, error, reset, setMessages }, status is idle, streaming, error or unavailable. | | ConversationList | Navigation-drawer list: new conversation, optional search, rename / delete callbacks, empty state, localized dates. | | ModelUnavailable | Downloading / loading / unavailable state with a determinate linear indicator and a retry button. | | CitedMarkdown, CitationChip, CitationList, RefusalNotice | Grounded answers: [n] markers as chips, the numbered sources, the "not established in the sources" notice. MessageBubble takes citations and refusal directly. | | MemoryPanel | Saved memories with per-item deletion and a confirmed "clear all" (confirmClear injects your own dialog). | | ChatIcon | The chat icons as inline Material Symbols SVG: no icon font is needed by the chat components. |

Markdown (and MessageBubble, CitedMarkdown) open external links with target="_blank" rel="noopener noreferrer" and take onLinkClick(href, event) (call event.preventDefault() to open the system browser from a Tauri webview) or renderLink. ChatComposer takes disabled (the model is unavailable: input, send, voice and selectors are inert), distinct from isSending.

Tests

bun test

test/preload.ts resolves @aphrody/m3-primitives to its sources, so the tests do not need a built dist.

Credits

Derived from SpaceUI @spacedrive/ai (MIT, see LICENSE.spaceui), rebuilt on Material Design 3. New code is Apache-2.0.