Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .claude/rules/dialtone-cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
paths:
- "packages/dialtone-cli/**"
---

# Dialtone CLI Rules

The CLI is a terminal interface over `@dialpad/dialtone-query-core`. It shares the same search engine as the MCP server.

## Architecture

- **Entry point**: `src/index.ts` โ€” citty command router + version check
- **Commands**: `src/commands/` โ€” one file per command (search, component, token, utility, prompt)
- **Formatters**: `src/formatters.ts` โ€” output rendering (minimal, markdown, json)
- **Debug suppression**: `src/silence-debug.ts` โ€” filters core's stderr debug logging

## Modifying Search Behavior

Edit the core package (`packages/dialtone-query-core/`), not the CLI. The CLI only handles argument parsing, output formatting, and the `prompt` command's LLM context generation.

## Build

```
pnpm nx run dialtone-query-core:build # core first
pnpm nx run dialtone-cli:build # then CLI
```

Rollup bundles everything (core + JSON data) into a single self-contained `build/index.js`.

## Adding a New Command

1. Create `src/commands/<name>.ts` with `defineCommand` from citty
2. Import search functions from `@dialpad/dialtone-query-core`
3. Register in `src/index.ts` under `subCommands`
4. Rebuild: `pnpm exec rollup -c`
32 changes: 29 additions & 3 deletions .claude/rules/mcp-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,34 @@ paths:

# MCP Server Rules

Data source: `src/data.ts` imports from `component-documentation.json` (generated by `scripts/build-dialtone-vue-docs.mjs`).
The MCP server is a thin transport layer over `@dialpad/dialtone-query-core`. All search logic, types, data loading, and formatting live in the core package.

Provides 3 search tools: `search_components`, `search_utility_classes`, `search_tokens`.
## Architecture

After changing the Vue component API surface or documentation JSON schema, rebuild: `pnpm nx run dialtone-mcp-server:build`
```text
dialtone-query-core (search engine)
โ”œโ”€โ”€ dialtone-mcp-server (MCP transport โ€” this package)
โ””โ”€โ”€ dialtone-cli (terminal interface)
```

- **Search logic**: `packages/dialtone-query-core/src/tools/`
- **Types**: `packages/dialtone-query-core/src/types.ts`
- **Data loading**: `packages/dialtone-query-core/src/data.ts`
- **MCP transport**: `packages/dialtone-mcp-server/src/index.ts` (only file in this package)
- **Client rules**: `packages/dialtone-mcp-server/client-rules.json` (MCP-specific, not in core)

## Modifying Search Behavior

Edit the core package, not this one. Changes to search algorithms, filters, or formatting propagate to both the MCP server and CLI automatically.

After changes: rebuild core first, then this package.

```bash
pnpm nx run dialtone-query-core:build
pnpm nx run dialtone-mcp-server:build
```

## Provides

4 search tools: `search_components`, `search_utility_classes`, `search_tokens`, `search_icons`
5 resources: utility-classes, tokens, components, icons, client-rules
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"dependencies": {
"@dialpad/dialtone-emojis": "workspace:*",
"@dialpad/dialtone-icons": "workspace:*",
"@dialpad/dialtone-cli": "workspace:*",
"@dialpad/dialtone-mcp-server": "workspace:*",
"@dialpad/dialtone-tokens": "workspace:*",
"@floating-ui/dom": "^1.6.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/dialtone-cli/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build/
node_modules/
184 changes: 184 additions & 0 deletions packages/dialtone-cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# Dialtone CLI

A command-line tool for searching and exploring the [Dialtone Design System](https://dialtone.dialpad.com). Look up components, design tokens, CSS utility classes, and icons from your terminal.

## Installation

```bash
npm install -g @dialpad/dialtone-cli
```

## Commands

### `dialtone search <query>`

Search across all domains โ€” components, tokens, utilities, and icons.

```bash
dialtone search button
dialtone search "padding 8px"
dialtone search "input|select|menu" # OR search
```

### `dialtone component <name>`

Show full component documentation.

```bash
dialtone component button
dialtone component DtModal
dialtone component button --props # props table
dialtone component button --props --describe # props with descriptions
dialtone component button --prop kind # single prop detail
dialtone component button --events # events only
dialtone component button --slots # slots only
dialtone component button --examples # usage example
```

### `dialtone token <query>`

Look up design tokens.

```bash
dialtone token "color foreground"
dialtone token "space 400"
dialtone token "color foreground" --values # show theme values
dialtone token "color foreground" --all # include HSL tokens
dialtone token "color foreground" --limit 0 # show all results
```

### `dialtone utility <query>`

Search CSS utility classes.

```bash
dialtone utility "padding 8px"
dialtone utility "display flex"
dialtone utility "margin auto"
```

### `dialtone prompt <name>`

Emit a compact, LLM-optimized context block for a component. Designed for piping into AI tools.

```bash
dialtone prompt button
dialtone prompt modal | pbcopy
dialtone prompt tooltip --format json
```

## Output Formats

All commands support `--format`:

| Flag | Output |
|------|--------|
| `--format minimal` | Plain text (default) |
| `--format markdown` | Markdown |
| `--format json` | Structured JSON |

## Updating

The CLI checks for updates automatically. To update:

```bash
npm install -g @dialpad/dialtone-cli@latest
```

The data (components, tokens, utilities, icons) is bundled at build time. Update the CLI to get the latest design system data.

## Claude Code Integration

The CLI can be used by Claude Code skills, hooks, and agents in any Dialpad repo. This is the recommended way to give Claude access to Dialtone when the MCP server isn't configured.

### Rules

Add a rule to your project's `.claude/rules/` that teaches Claude about the CLI:

```markdown
---
description: "Dialtone design system lookups"
---

# Dialtone Design System

When working with Dialtone components, tokens, or utility classes, use the `dialtone` CLI for lookups:

- Component API: `dialtone component <name> --props`
- Single prop: `dialtone component <name> --prop <prop>`
- Token lookup: `dialtone token "<query>"`
- Utility classes: `dialtone utility "<query>"`
- Structured data: add `--format json` to any command

Prefer the CLI over reading source files for design system information. It searches
the full published API and filters deprecated items automatically.
```

### Skills

Wrap CLI commands in a skill for common workflows:

```markdown
---
description: "Look up a Dialtone component. Use when referencing component props, events, or slots."
---

# Dialtone Lookup

1. Run `dialtone component <name> --format json` to get full component data
2. If you need specific prop values, run `dialtone component <name> --prop <prop>`
3. For LLM-optimized context, run `dialtone prompt <name>`
```

### Hooks

Use a `UserPromptSubmit` hook to auto-inject Dialtone context when a user mentions a component:

```json
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "(?:Dt[A-Z]\\w+|dialtone\\s+component)",
"command": "dialtone prompt \"$MATCH\" --format json 2>/dev/null || true"
}
]
}
}
```

### Agents

An agent can call the CLI via Bash to research design system questions:

```markdown
---
description: "Research Dialtone design system components, tokens, and utilities."
---

Use the `dialtone` CLI to look up design system information:

- `dialtone search "<query>"` โ€” broad search across all domains
- `dialtone search "<term1>|<term2>"` โ€” OR search across multiple terms
- `dialtone component <name> --format json` โ€” full component data
- `dialtone token "<query>" --format json` โ€” token data
- `dialtone utility "<query>" --format json` โ€” utility class data

Always use `--format json` when processing results programmatically.
```

### CLI vs MCP Server

Install both. They're complementary โ€” the CLI for fast lookups, the MCP server for deep exploration.

**CLI** โ€” token-efficient plain text. Best for direct lookups: "what props does this component have?", "what tokens match this query?" Returns compact output that costs minimal context window tokens.

**MCP server** โ€” structured data + resources protocol. Best when the LLM needs to pull full datasets, cross-reference components with tokens, or reason through complex design system questions. The resources (`dialtone://components`, `dialtone://tokens`) give access to the complete data.

| Use case | Recommended |
|----------|-------------|
| Quick lookups (props, tokens, classes) | CLI |
| Deep reasoning across the design system | MCP server |
| Shell scripts and automation | CLI |
| Piping context into AI tools | CLI (`dialtone prompt`) |
| Non-Claude MCP clients (Cursor, Windsurf) | MCP server |
47 changes: 47 additions & 0 deletions packages/dialtone-cli/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@dialpad/dialtone-cli",
"version": "1.0.0",
"description": "CLI for searching and exploring the Dialtone Design System",
"main": "build/index.js",
"type": "module",
"bin": {
"dialtone": "build/index.js"
},
"files": [
"build"
],
"scripts": {
"build": "rollup -c",
"start": "node build/index.js",
"dev": "tsx src/index.ts"
},
"dependencies": {
"citty": "^0.1.6",
"cli-table3": "^0.6.5"
},
"devDependencies": {
"@dialpad/dialtone-css": "workspace:*",
"@dialpad/dialtone-icons": "workspace:*",
"@dialpad/dialtone-query-core": "workspace:*",
"@dialpad/dialtone-vue": "workspace:^3",
"@rollup/plugin-commonjs": "^28.0.0",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.2.0",
"@rollup/plugin-typescript": "^11.1.0",
"@types/node": "24.3.1",
"rollup": "^4.0.0",
"tsx": "^4.0.0",
"typescript": "^5.2"
},
"keywords": [
"dialtone",
"design-system",
"cli"
],
"repository": {
"type": "git",
"url": "https://github.com/dialpad/dialtone.git",
"directory": "packages/dialtone-cli"
},
"license": "MIT"
}
33 changes: 33 additions & 0 deletions packages/dialtone-cli/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "dialtone-cli",
"targets": {
"build": {
"executor": "nx:run-commands",
"dependsOn": ["dialtone-query-core:build"],
"inputs": [
"{projectRoot}/src/**/*",
"{projectRoot}/package.json",
"{projectRoot}/tsconfig.json",
"{projectRoot}/rollup.config.js"
],
"outputs": ["{projectRoot}/build"],
"options": {
"cwd": "{projectRoot}",
"command": "pnpm exec rollup -c"
}
},
"publish": {
"executor": "nx:run-commands",
"options": {
"command": "pnpm publish --filter ./packages/dialtone-cli"
}
},
"release": {
"executor": "nx:run-commands",
"options": {
"command": "pnpm semantic-release-plus --extends ./packages/dialtone-cli/release-ci.config.cjs && sleep 3",
"parallel": false
}
}
}
}
Loading
Loading