@turquoisehealth/pit-viper 2.179.1-dev.0 → 2.181.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claude-plugin/.claude-plugin/plugin.json +8 -2
- package/claude-plugin/.mcp.json +8 -0
- package/claude-plugin/CLAUDE.md +71 -250
- package/claude-plugin/README.md +123 -69
- package/claude-plugin/skills/pit-viper/SKILL.md +180 -0
- package/claude-plugin/skills/pit-viper/references/design-language.md +80 -0
- package/claude-plugin/skills/pit-viper/references/design-rules.md +254 -0
- package/claude-plugin/skills/pit-viper/references/html-patterns.md +451 -0
- package/claude-plugin/skills/pit-viper/references/layout-patterns.md +359 -0
- package/claude-plugin/skills/pit-viper/references/patterns-core.md +97 -0
- package/claude-plugin/skills/pit-viper/references/theme-guide.md +149 -0
- package/claude-plugin/skills/pit-viper/references/vue-guidelines.md +513 -0
- package/package.json +3 -3
- package/pv-components/dist/stats/vue/base/stats.html +1 -1
- package/pv-components/dist/stats/vue/visualizations/stats.html +1 -1
- package/pv-components/dist/stats/web/pv-menu-stats.html +1 -1
- package/pv-components/dist/stats/web/pv-multi-select-button-stats.html +1 -1
- package/pv-components/dist/stats/web/pv-query-builder-input-stats.html +1 -1
- package/pv-components/dist/stats/web/pv-select-button-stats.html +1 -1
- package/pv-components/dist/vue/base/pv-components-base.mjs +2 -2
- package/pv-components/dist/vue/base/pv-components-base.mjs.map +1 -1
- package/pv-components/dist/vue/visualizations/components/tables/PvDataTable/filters/filterHelpers.d.ts +1 -1
- package/pv-components/dist/vue/visualizations/pv-components-visualizations.mjs +5 -5
- package/pv-components/dist/vue/visualizations/pv-components-visualizations.mjs.map +1 -1
- package/pv-components/dist/web/components/pv-menu/pv-menu.js +2 -2
- package/pv-components/dist/web/components/pv-multi-select-button/pv-multi-select-button.js +2 -2
- package/pv-components/dist/web/components/pv-query-builder-input/pv-query-builder-input.js +2 -2
- package/pv-components/dist/web/components/pv-select-button/pv-select-button.js +2 -2
- package/pv-components/dist/web/pv-components.iife.js +1 -1
- package/pv-components/dist/web/pv-components.iife.js.map +1 -1
- package/claude-plugin/skills/audit/SKILL.md +0 -125
- package/claude-plugin/skills/create/SKILL.md +0 -389
- package/claude-plugin/skills/resolve/SKILL.md +0 -142
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: audit
|
|
3
|
-
description: Check Vue/HTML files for Pit Viper design system compliance and auto-fix violations
|
|
4
|
-
argument-hint: "[file-path | --all]"
|
|
5
|
-
allowed-tools: "Read, Glob, Grep, Edit, Bash"
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Audit Design System Compliance
|
|
9
|
-
|
|
10
|
-
Check Vue and HTML files for Pit Viper design system violations and automatically fix them.
|
|
11
|
-
|
|
12
|
-
## Input
|
|
13
|
-
|
|
14
|
-
`$ARGUMENTS` — One of:
|
|
15
|
-
- File path(s) to audit (e.g., `src/components/MyComponent.vue`)
|
|
16
|
-
- `--all` to audit all `.vue` and `.html` files in the project
|
|
17
|
-
- Empty: auto-detect changed files via `git diff --name-only`
|
|
18
|
-
|
|
19
|
-
## Workflow
|
|
20
|
-
|
|
21
|
-
### Step 1: Identify files to audit
|
|
22
|
-
|
|
23
|
-
- If file path(s) provided, use those
|
|
24
|
-
- If `--all`, glob for `**/*.vue` and `**/*.html`
|
|
25
|
-
- If empty, run `git diff --name-only` to find changed `.vue` and `.html` files
|
|
26
|
-
|
|
27
|
-
If no files to audit, report "No files to audit" and exit.
|
|
28
|
-
|
|
29
|
-
### Step 2: Read each file
|
|
30
|
-
|
|
31
|
-
For each file:
|
|
32
|
-
- `.vue` files: check `<template>` and `<style>` sections
|
|
33
|
-
- `.html` files: check all markup and inline styles
|
|
34
|
-
|
|
35
|
-
### Step 3: Check for violations
|
|
36
|
-
|
|
37
|
-
#### Custom CSS (auto-fix: replace with Pit Viper classes)
|
|
38
|
-
|
|
39
|
-
- `<style>` blocks — remove and replace CSS rules with Pit Viper utility classes
|
|
40
|
-
- `style="..."` inline attributes — remove and apply equivalent Pit Viper classes
|
|
41
|
-
|
|
42
|
-
#### Raw HTML elements (auto-fix: replace with Pit Viper components)
|
|
43
|
-
|
|
44
|
-
These raw elements should use Pit Viper equivalents:
|
|
45
|
-
|
|
46
|
-
| Raw Element | Pit Viper Component |
|
|
47
|
-
|-------------|---------------------|
|
|
48
|
-
| `<button>` | `<PvButton>` |
|
|
49
|
-
| `<table>` | `<PvDataTable>` |
|
|
50
|
-
| `<input type="text">` | `<PvInput>` |
|
|
51
|
-
| `<input type="checkbox">` | `<PvCheckbox>` |
|
|
52
|
-
| `<input type="search">` | `<PvSearchInput>` |
|
|
53
|
-
| `<select>` | `<PvSelectButton>` |
|
|
54
|
-
| `<textarea>` | `<PvTextArea>` |
|
|
55
|
-
| `<dialog>` | `<PvModal>` |
|
|
56
|
-
|
|
57
|
-
**Exceptions (allowed):** Basic structural HTML is fine:
|
|
58
|
-
`<div>`, `<span>`, `<p>`, `<h1>`-`<h6>`, `<a>`, `<img>`, `<ul>`, `<ol>`, `<li>`, `<section>`, `<header>`, `<footer>`, `<nav>`, `<main>`, `<article>`, `<aside>`, `<template>`, `<slot>`, `<form>`, `<label>`
|
|
59
|
-
|
|
60
|
-
#### Invalid CSS class names
|
|
61
|
-
|
|
62
|
-
Read the Pit Viper CSS file to validate class names:
|
|
63
|
-
```
|
|
64
|
-
node_modules/@turquoisehealth/pit-viper/_site/assets/css/pit-viper-v2.css
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Flag any `class="..."` that contains classes not defined in `pit-viper-v2.css`. Suggest the closest valid class or remove invalid classes.
|
|
68
|
-
|
|
69
|
-
#### Wrong import paths (Vue only)
|
|
70
|
-
|
|
71
|
-
Check that Pit Viper imports use correct paths:
|
|
72
|
-
- Base components: `@turquoisehealth/pit-viper/components`
|
|
73
|
-
- Visualizations: `@turquoisehealth/pit-viper/components/visualizations`
|
|
74
|
-
|
|
75
|
-
### Step 4: Apply fixes
|
|
76
|
-
|
|
77
|
-
For each violation:
|
|
78
|
-
1. Log the violation (file, line, issue)
|
|
79
|
-
2. Apply the auto-fix
|
|
80
|
-
3. Log what was changed
|
|
81
|
-
|
|
82
|
-
### Step 5: Report
|
|
83
|
-
|
|
84
|
-
Output a summary:
|
|
85
|
-
|
|
86
|
-
```
|
|
87
|
-
## Audit Results
|
|
88
|
-
|
|
89
|
-
### src/components/MyComponent.vue
|
|
90
|
-
|
|
91
|
-
**Violations found: 3**
|
|
92
|
-
|
|
93
|
-
1. Line 15: `<style>` block with custom CSS
|
|
94
|
-
→ Removed, applied `.pv-flex .pv-stack-16` to container
|
|
95
|
-
|
|
96
|
-
2. Line 23: Raw `<button>` element
|
|
97
|
-
→ Replaced with `<PvButton>`
|
|
98
|
-
|
|
99
|
-
3. Line 31: Invalid class `custom-spacing`
|
|
100
|
-
→ Replaced with `.pv-stack-8`
|
|
101
|
-
|
|
102
|
-
---
|
|
103
|
-
|
|
104
|
-
**Files audited:** 2
|
|
105
|
-
**Violations found:** 5
|
|
106
|
-
**Violations fixed:** 5
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
If no violations found:
|
|
110
|
-
```
|
|
111
|
-
## Audit Results
|
|
112
|
-
|
|
113
|
-
All files pass design system compliance.
|
|
114
|
-
|
|
115
|
-
**Files audited:** 3
|
|
116
|
-
**Violations found:** 0
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
## Rules
|
|
120
|
-
|
|
121
|
-
- Always auto-fix violations (don't just report)
|
|
122
|
-
- Preserve file structure and formatting where possible
|
|
123
|
-
- If a fix is ambiguous (multiple valid options), pick the most common pattern
|
|
124
|
-
- If Pit Viper CSS file is not found, warn that `@turquoisehealth/pit-viper` may not be installed
|
|
125
|
-
- Do not modify files outside the audit scope
|
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: create
|
|
3
|
-
description: Build complete Pit Viper pages and layouts from natural language descriptions
|
|
4
|
-
argument-hint: "<what you want to build>"
|
|
5
|
-
allowed-tools: "Read, Glob, Grep, WebFetch, Write, Edit, mcp__pit-viper__search, mcp__pit-viper__storybook_get_component, mcp__pit-viper__css_get_docs, mcp__pit-viper__css_list_tokens, mcp__pit-viper__css_search_classes"
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Create Pit Viper Pages
|
|
9
|
-
|
|
10
|
-
Build complete, working pages from natural language descriptions. No Vue, imports, or CSS knowledge required.
|
|
11
|
-
|
|
12
|
-
## Input
|
|
13
|
-
|
|
14
|
-
`$ARGUMENTS` — Natural language description of what to build:
|
|
15
|
-
- "a dashboard with a sidebar and data table"
|
|
16
|
-
- "a login form for the marketing site"
|
|
17
|
-
- "a settings page with tabs for profile and notifications"
|
|
18
|
-
|
|
19
|
-
### Optional Flags
|
|
20
|
-
|
|
21
|
-
- `--theme=platform` or `--theme=consumer` — Override auto-detected theme
|
|
22
|
-
- `--format=html` — Output plain HTML with web components instead of Vue SFC
|
|
23
|
-
|
|
24
|
-
## Workflow
|
|
25
|
-
|
|
26
|
-
### Step 1: Parse User Intent
|
|
27
|
-
|
|
28
|
-
Extract from the description:
|
|
29
|
-
1. **Page type:** dashboard, form, settings, landing page, list view, detail view
|
|
30
|
-
2. **Components needed:** tables, charts, inputs, modals, etc.
|
|
31
|
-
3. **Theme preference:** detect from keywords or use override
|
|
32
|
-
|
|
33
|
-
### Step 2: Detect Theme
|
|
34
|
-
|
|
35
|
-
**Consumer theme triggers:** marketing, consumer, public, landing, website, customer-facing, external
|
|
36
|
-
**Platform theme triggers:** dashboard, admin, internal, platform, tool, portal, app (default)
|
|
37
|
-
|
|
38
|
-
| Theme | CSS URL | Font | Heading-1 |
|
|
39
|
-
|-------|---------|------|-----------|
|
|
40
|
-
| Platform | `https://pitviper.turquoise.health/assets/css/pit-viper-v2.css` | Inter | 1.25rem (compact) |
|
|
41
|
-
| Consumer | `https://pitviper.turquoise.health/assets/css/pit-viper-consumer.css` | GT Standard | 3.875rem (large) |
|
|
42
|
-
|
|
43
|
-
### Step 3: Detect Output Format
|
|
44
|
-
|
|
45
|
-
**HTML output triggers:** HTML, static site, no framework, plain, vanilla JS, web component
|
|
46
|
-
**Vue SFC output:** Default for all other cases
|
|
47
|
-
|
|
48
|
-
### Step 4: Select Layout Pattern
|
|
49
|
-
|
|
50
|
-
Match the description to one of these patterns:
|
|
51
|
-
|
|
52
|
-
#### Dashboard Pattern
|
|
53
|
-
```
|
|
54
|
-
PvSidePanel (showLeftSidebar=true)
|
|
55
|
-
├── #left-sidebar: Navigation menu with links
|
|
56
|
-
└── #main:
|
|
57
|
-
├── Header: h1.pv-heading-1 + optional PvBreadcrumbs
|
|
58
|
-
├── Toolbar: PvSearchInput + PvSelectButton filters
|
|
59
|
-
└── Content: PvDataTable or PvDataTableWithChart
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
#### Form Pattern
|
|
63
|
-
```
|
|
64
|
-
PvCard
|
|
65
|
-
├── Header: h2.pv-heading-2
|
|
66
|
-
├── Body: Form fields in .pv-flow-16
|
|
67
|
-
│ ├── PvInput (text fields)
|
|
68
|
-
│ ├── PvSelectButton (dropdowns)
|
|
69
|
-
│ ├── PvCheckbox / PvSwitch (toggles)
|
|
70
|
-
│ └── PvTextArea (multi-line)
|
|
71
|
-
└── Footer: .pv-flex with PvButton (primary) + PvButton (ghost)
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
#### Settings Pattern
|
|
75
|
-
```
|
|
76
|
-
PvTabs (v-model bound to activeTab)
|
|
77
|
-
└── Tab panels
|
|
78
|
-
├── PvAccordion sections for grouping
|
|
79
|
-
└── Form elements within each section
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
#### List View Pattern
|
|
83
|
-
```
|
|
84
|
-
Container
|
|
85
|
-
├── Header: h1.pv-heading-1 + PvButton (add new)
|
|
86
|
-
├── Filters: PvSearchInput + PvSelectButton
|
|
87
|
-
├── Table: PvDataTable with actions column
|
|
88
|
-
└── Footer: PvPagination
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
#### Detail View Pattern
|
|
92
|
-
```
|
|
93
|
-
Container
|
|
94
|
-
├── Header: PvBreadcrumbs + h1.pv-heading-1
|
|
95
|
-
├── Metadata: .pv-flex with PvTag, PvPill, status
|
|
96
|
-
└── Content: PvCard sections with data
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
#### Marketing/Landing Pattern (Consumer theme)
|
|
100
|
-
```
|
|
101
|
-
Page container
|
|
102
|
-
├── Hero: .pv-surface-brand-accent
|
|
103
|
-
│ ├── h1.pv-heading-1 (large in consumer theme)
|
|
104
|
-
│ ├── p.pv-text-body-xl
|
|
105
|
-
│ └── PvButton (size="lg")
|
|
106
|
-
├── Features: .pv-flex grid of PvCard
|
|
107
|
-
└── CTA: .pv-surface-brand
|
|
108
|
-
├── h2.pv-heading-2.pv-text-inverse
|
|
109
|
-
└── PvButton (inverse)
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### Step 5: Generate Code
|
|
113
|
-
|
|
114
|
-
#### Vue SFC Output (Default)
|
|
115
|
-
|
|
116
|
-
Generate a complete `<script setup>` + `<template>` file:
|
|
117
|
-
|
|
118
|
-
```vue
|
|
119
|
-
<script setup>
|
|
120
|
-
import { ref } from 'vue'
|
|
121
|
-
// Import base components
|
|
122
|
-
import { PvButton, PvInput, PvIcon } from '@turquoisehealth/pit-viper/components'
|
|
123
|
-
// Import visualization components (if needed)
|
|
124
|
-
import { PvDataTable, PvChart } from '@turquoisehealth/pit-viper/components/visualizations'
|
|
125
|
-
// Import layout components (if needed)
|
|
126
|
-
import PvSidePanel from '@turquoisehealth/pit-viper/components/layout/PvSidePanel/PvSidePanel.vue'
|
|
127
|
-
|
|
128
|
-
// Reactive state
|
|
129
|
-
const someValue = ref('')
|
|
130
|
-
</script>
|
|
131
|
-
|
|
132
|
-
<template>
|
|
133
|
-
<!-- Complete markup with Pit Viper components and classes -->
|
|
134
|
-
</template>
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
#### HTML Output (Web Components)
|
|
138
|
-
|
|
139
|
-
Generate complete HTML with CDN links:
|
|
140
|
-
|
|
141
|
-
```html
|
|
142
|
-
<!DOCTYPE html>
|
|
143
|
-
<html lang="en">
|
|
144
|
-
<head>
|
|
145
|
-
<meta charset="UTF-8">
|
|
146
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
147
|
-
<title>Page Title</title>
|
|
148
|
-
<!-- Pit Viper CSS (Platform or Consumer) -->
|
|
149
|
-
<link rel="stylesheet" href="https://pitviper.turquoise.health/assets/css/pit-viper-v2.css">
|
|
150
|
-
<!-- Pit Viper Web Components -->
|
|
151
|
-
<script src="https://unpkg.com/@turquoisehealth/pit-viper/pv-components/dist/web/pv-components.iife.js"></script>
|
|
152
|
-
</head>
|
|
153
|
-
<body>
|
|
154
|
-
<!-- Web components use kebab-case: pv-button, pv-input, etc. -->
|
|
155
|
-
<pv-button label="Click me"></pv-button>
|
|
156
|
-
</body>
|
|
157
|
-
</html>
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Step 6: Validate Output
|
|
161
|
-
|
|
162
|
-
Before presenting the code:
|
|
163
|
-
1. Verify all imports use correct paths
|
|
164
|
-
2. Ensure all CSS classes exist (pv-* prefix)
|
|
165
|
-
3. Check component props match the API
|
|
166
|
-
4. Include sample data so the code runs immediately
|
|
167
|
-
|
|
168
|
-
### Step 7: Present Output
|
|
169
|
-
|
|
170
|
-
Return:
|
|
171
|
-
1. The complete code (Vue SFC or HTML)
|
|
172
|
-
2. A note about which CSS file to include (if Vue)
|
|
173
|
-
3. Brief explanation of what was generated
|
|
174
|
-
|
|
175
|
-
## Component Quick Reference
|
|
176
|
-
|
|
177
|
-
### Base Components (from `@turquoisehealth/pit-viper/components`)
|
|
178
|
-
|
|
179
|
-
| Component | Purpose | Key Props |
|
|
180
|
-
|-----------|---------|-----------|
|
|
181
|
-
| `PvButton` | All buttons | `variant`, `size`, `leftIcon`, `loading`, `disabled` |
|
|
182
|
-
| `PvInput` | Text inputs | `v-model`, `type`, `placeholder`, `error`, `disabled` |
|
|
183
|
-
| `PvTextArea` | Multi-line input | `v-model`, `placeholder`, `rows` |
|
|
184
|
-
| `PvSelectButton` | Dropdown | `v-model`, `options`, `label`, `placeholder` |
|
|
185
|
-
| `PvMultiSelectButton` | Multi-select dropdown | `v-model`, `options`, `label` |
|
|
186
|
-
| `PvCheckbox` | Checkbox | `v-model`, `label`, `disabled` |
|
|
187
|
-
| `PvSwitch` | Toggle switch | `v-model`, `label`, `size` |
|
|
188
|
-
| `PvSearchInput` | Search field | `v-model`, `placeholder` |
|
|
189
|
-
| `PvTabs` | Tab navigation | `v-model`, `tabs` (array of {label, value}) |
|
|
190
|
-
| `PvAccordion` | Collapsible section | `v-model`, `header` |
|
|
191
|
-
| `PvModal` | Dialog | `v-model`, `header`; slots: `#body`, `#footer` |
|
|
192
|
-
| `PvDrawer` | Side panel | `v-model`, `header`; slots: `#default`, `#footer` |
|
|
193
|
-
| `PvCard` | Card container | slots: `#header`, `#default`, `#footer` |
|
|
194
|
-
| `PvToast` | Notification | `label`, `variant` (success/error/info) |
|
|
195
|
-
| `PvIcon` | SVG icon | `name`, `size` (12/16/20/24) |
|
|
196
|
-
| `PvBreadcrumbs` | Navigation | `items` (array of {label, href}) |
|
|
197
|
-
| `PvPagination` | Page controls | `v-model`, `totalPages` |
|
|
198
|
-
| `PvTag` | Inline tag | `label`, `variant` |
|
|
199
|
-
| `PvPill` | Rounded badge | `label`, `variant` |
|
|
200
|
-
| `PvAvatar` | User avatar | `name`, `src`, `size` |
|
|
201
|
-
| `PvBanner` | Alert banner | `variant`, `message` |
|
|
202
|
-
| `PvSpinner` | Loading spinner | `size`, `variant` |
|
|
203
|
-
| `PvSkeleton` | Loading placeholder | `width`, `height` |
|
|
204
|
-
|
|
205
|
-
### Visualization Components (from `@turquoisehealth/pit-viper/components/visualizations`)
|
|
206
|
-
|
|
207
|
-
| Component | Purpose | Key Props |
|
|
208
|
-
|-----------|---------|-----------|
|
|
209
|
-
| `PvDataTable` | Data grid | `rowData`, `colDefs`, `pagination` |
|
|
210
|
-
| `PvChart` | Charts | `type`, `data`, `options` |
|
|
211
|
-
| `PvDataTableWithChart` | Combined view | `rowData`, `colDefs`, `chartType` |
|
|
212
|
-
|
|
213
|
-
### Layout Components
|
|
214
|
-
|
|
215
|
-
| Component | Import Path | Purpose |
|
|
216
|
-
|-----------|-------------|---------|
|
|
217
|
-
| `PvSidePanel` | `@turquoisehealth/pit-viper/components/layout/PvSidePanel/PvSidePanel.vue` | 3-column layout |
|
|
218
|
-
|
|
219
|
-
## CSS Quick Reference
|
|
220
|
-
|
|
221
|
-
### Typography
|
|
222
|
-
- `.pv-heading-1` through `.pv-heading-5` — Headings
|
|
223
|
-
- `.pv-text-body-xl`, `-lg`, `-md`, `-sm` — Body text
|
|
224
|
-
- `.pv-text-title-md`, `-sm` — Semibold titles
|
|
225
|
-
|
|
226
|
-
### Spacing
|
|
227
|
-
- `.pv-stack-8`, `-16`, `-24`, `-32` — Vertical margin (margin-bottom)
|
|
228
|
-
- `.pv-inset-square-8`, `-16`, `-24` — Padding (all sides)
|
|
229
|
-
- `.pv-flow-8`, `-16`, `-24` — Gap between children
|
|
230
|
-
|
|
231
|
-
### Layout
|
|
232
|
-
- `.pv-flex` — Flexbox with 0.5rem gap
|
|
233
|
-
- `.pv-flex-vertical` — Column direction
|
|
234
|
-
- `.pv-space-between` — Justify space-between
|
|
235
|
-
|
|
236
|
-
### Colors
|
|
237
|
-
- `.pv-text-default`, `.pv-text-subdued`, `.pv-text-brand` — Text colors
|
|
238
|
-
- `.pv-surface`, `.pv-surface-accent`, `.pv-surface-brand` — Backgrounds
|
|
239
|
-
|
|
240
|
-
### Borders
|
|
241
|
-
- `.pv-radius`, `.pv-radius-sm`, `.pv-radius-lg` — Border radius
|
|
242
|
-
|
|
243
|
-
## Rules
|
|
244
|
-
|
|
245
|
-
1. **Always generate complete, runnable code** — No placeholders or "add your code here"
|
|
246
|
-
2. **Include sample data** — Tables should have 3-5 sample rows, forms should have default values
|
|
247
|
-
3. **Use only valid Pit Viper classes** — No custom CSS, no Tailwind
|
|
248
|
-
4. **Match theme to use case** — Marketing = Consumer, Dashboard = Platform
|
|
249
|
-
5. **Prefer Vue SFC unless HTML requested** — Vue is the primary framework
|
|
250
|
-
6. **Use semantic component choices** — PvSelectButton for dropdowns, not raw `<select>`
|
|
251
|
-
|
|
252
|
-
## Examples
|
|
253
|
-
|
|
254
|
-
### Example 1: Simple Login Form
|
|
255
|
-
|
|
256
|
-
**Input:** "create a login form"
|
|
257
|
-
|
|
258
|
-
**Output:**
|
|
259
|
-
```vue
|
|
260
|
-
<script setup>
|
|
261
|
-
import { ref } from 'vue'
|
|
262
|
-
import { PvButton, PvInput, PvCard } from '@turquoisehealth/pit-viper/components'
|
|
263
|
-
|
|
264
|
-
const email = ref('')
|
|
265
|
-
const password = ref('')
|
|
266
|
-
const loading = ref(false)
|
|
267
|
-
|
|
268
|
-
const handleLogin = () => {
|
|
269
|
-
loading.value = true
|
|
270
|
-
// Add login logic here
|
|
271
|
-
}
|
|
272
|
-
</script>
|
|
273
|
-
|
|
274
|
-
<template>
|
|
275
|
-
<div class="pv-flex" style="min-height: 100vh; align-items: center; justify-content: center;">
|
|
276
|
-
<PvCard style="width: 400px;">
|
|
277
|
-
<template #header>
|
|
278
|
-
<h1 class="pv-heading-2">Sign In</h1>
|
|
279
|
-
</template>
|
|
280
|
-
|
|
281
|
-
<form @submit.prevent="handleLogin" class="pv-flow-16">
|
|
282
|
-
<div>
|
|
283
|
-
<label class="pv-text-title-sm pv-stack-4">Email</label>
|
|
284
|
-
<PvInput v-model="email" type="email" placeholder="you@example.com" />
|
|
285
|
-
</div>
|
|
286
|
-
|
|
287
|
-
<div>
|
|
288
|
-
<label class="pv-text-title-sm pv-stack-4">Password</label>
|
|
289
|
-
<PvInput v-model="password" type="password" placeholder="Enter password" />
|
|
290
|
-
</div>
|
|
291
|
-
|
|
292
|
-
<PvButton type="submit" :loading="loading" style="width: 100%;">
|
|
293
|
-
Sign In
|
|
294
|
-
</PvButton>
|
|
295
|
-
</form>
|
|
296
|
-
|
|
297
|
-
<template #footer>
|
|
298
|
-
<p class="pv-text-body-sm pv-text-subdued">
|
|
299
|
-
Don't have an account? <a href="#" class="pv-text-brand">Sign up</a>
|
|
300
|
-
</p>
|
|
301
|
-
</template>
|
|
302
|
-
</PvCard>
|
|
303
|
-
</div>
|
|
304
|
-
</template>
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### Example 2: Dashboard with Sidebar
|
|
308
|
-
|
|
309
|
-
**Input:** "create a dashboard with sidebar navigation and a user table"
|
|
310
|
-
|
|
311
|
-
**Output:**
|
|
312
|
-
```vue
|
|
313
|
-
<script setup>
|
|
314
|
-
import { ref } from 'vue'
|
|
315
|
-
import { PvButton, PvSearchInput, PvIcon } from '@turquoisehealth/pit-viper/components'
|
|
316
|
-
import { PvDataTable } from '@turquoisehealth/pit-viper/components/visualizations'
|
|
317
|
-
import PvSidePanel from '@turquoisehealth/pit-viper/components/layout/PvSidePanel/PvSidePanel.vue'
|
|
318
|
-
|
|
319
|
-
const searchQuery = ref('')
|
|
320
|
-
|
|
321
|
-
const users = ref([
|
|
322
|
-
{ id: 1, name: 'Alice Johnson', email: 'alice@example.com', role: 'Admin', status: 'Active' },
|
|
323
|
-
{ id: 2, name: 'Bob Smith', email: 'bob@example.com', role: 'Editor', status: 'Active' },
|
|
324
|
-
{ id: 3, name: 'Carol White', email: 'carol@example.com', role: 'Viewer', status: 'Pending' },
|
|
325
|
-
])
|
|
326
|
-
|
|
327
|
-
const colDefs = [
|
|
328
|
-
{ field: 'name', headerName: 'Name', flex: 1 },
|
|
329
|
-
{ field: 'email', headerName: 'Email', flex: 1 },
|
|
330
|
-
{ field: 'role', headerName: 'Role', width: 120 },
|
|
331
|
-
{ field: 'status', headerName: 'Status', width: 100 },
|
|
332
|
-
]
|
|
333
|
-
|
|
334
|
-
const navItems = [
|
|
335
|
-
{ label: 'Dashboard', icon: 'home', active: true },
|
|
336
|
-
{ label: 'Users', icon: 'user' },
|
|
337
|
-
{ label: 'Settings', icon: 'gear' },
|
|
338
|
-
]
|
|
339
|
-
</script>
|
|
340
|
-
|
|
341
|
-
<template>
|
|
342
|
-
<div style="height: 100vh;">
|
|
343
|
-
<PvSidePanel :showLeftSidebar="true" :showRightSidebar="false">
|
|
344
|
-
<template #left-sidebar>
|
|
345
|
-
<nav class="pv-inset-square-16">
|
|
346
|
-
<p class="pv-text-title-md pv-stack-24">My App</p>
|
|
347
|
-
<ul style="list-style: none; padding: 0; margin: 0;">
|
|
348
|
-
<li
|
|
349
|
-
v-for="item in navItems"
|
|
350
|
-
:key="item.label"
|
|
351
|
-
class="pv-flex pv-inset-squish-8 pv-radius"
|
|
352
|
-
:class="{ 'pv-surface-highlight': item.active }"
|
|
353
|
-
style="cursor: pointer; --flex-gap: 0.75rem;"
|
|
354
|
-
>
|
|
355
|
-
<PvIcon :name="item.icon" :size="16" />
|
|
356
|
-
<span class="pv-text-body-md">{{ item.label }}</span>
|
|
357
|
-
</li>
|
|
358
|
-
</ul>
|
|
359
|
-
</nav>
|
|
360
|
-
</template>
|
|
361
|
-
|
|
362
|
-
<template #main>
|
|
363
|
-
<div class="pv-inset-square-24">
|
|
364
|
-
<div class="pv-flex pv-space-between pv-stack-24">
|
|
365
|
-
<h1 class="pv-heading-1">Users</h1>
|
|
366
|
-
<PvButton leftIcon="plus">Add User</PvButton>
|
|
367
|
-
</div>
|
|
368
|
-
|
|
369
|
-
<div class="pv-stack-16">
|
|
370
|
-
<PvSearchInput
|
|
371
|
-
v-model="searchQuery"
|
|
372
|
-
placeholder="Search users..."
|
|
373
|
-
style="max-width: 300px;"
|
|
374
|
-
/>
|
|
375
|
-
</div>
|
|
376
|
-
|
|
377
|
-
<PvDataTable
|
|
378
|
-
:rowData="users"
|
|
379
|
-
:colDefs="colDefs"
|
|
380
|
-
style="height: 400px;"
|
|
381
|
-
/>
|
|
382
|
-
</div>
|
|
383
|
-
</template>
|
|
384
|
-
</PvSidePanel>
|
|
385
|
-
</div>
|
|
386
|
-
</template>
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
**Note:** Include `pit-viper-v2.css` in your app's HTML or main entry file.
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: resolve
|
|
3
|
-
description: Find the correct Pit Viper component for a UI element
|
|
4
|
-
argument-hint: "<description | figma-url | html-snippet>"
|
|
5
|
-
allowed-tools: "Read, Glob, Grep, WebFetch, mcp__figma__get_code_connect_map, mcp__figma__get_code_connect_suggestions, mcp__figma__get_design_context, mcp__claude_ai_Figma__get_code_connect_map, mcp__claude_ai_Figma__get_code_connect_suggestions, mcp__claude_ai_Figma__get_design_context, mcp__pit-viper__search, mcp__pit-viper__storybook_get_component, mcp__pit-viper__storybook_list_components, mcp__pit-viper__css_get_docs, mcp__pit-viper__css_list_components"
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Resolve Pit Viper Component
|
|
9
|
-
|
|
10
|
-
Given a UI element description, Figma URL, or HTML snippet, find the correct Pit Viper component with props and usage example.
|
|
11
|
-
|
|
12
|
-
## Input
|
|
13
|
-
|
|
14
|
-
`$ARGUMENTS` — One of:
|
|
15
|
-
- Text description (e.g., "dropdown with search", "data table with pagination")
|
|
16
|
-
- Figma URL (extracts component via MCP)
|
|
17
|
-
- HTML/code snippet to convert
|
|
18
|
-
|
|
19
|
-
## Resolution Order
|
|
20
|
-
|
|
21
|
-
### 1. Code Connect (Figma URLs only)
|
|
22
|
-
|
|
23
|
-
If input is a Figma URL:
|
|
24
|
-
1. Extract `fileKey` and `nodeId` from the URL
|
|
25
|
-
2. Call `get_code_connect_map` to check for direct Figma-to-code mappings
|
|
26
|
-
3. If a mapping exists, use it and skip to output
|
|
27
|
-
|
|
28
|
-
### 2. Component Mapping Rules
|
|
29
|
-
|
|
30
|
-
Apply these built-in mappings before searching external sources:
|
|
31
|
-
|
|
32
|
-
| Design Element | Component | Import Path |
|
|
33
|
-
|----------------|-----------|-------------|
|
|
34
|
-
| Any table or data grid | `PvDataTable` | `@turquoisehealth/pit-viper/components/visualizations` |
|
|
35
|
-
| Any chart or visualization | `PvChart` | `@turquoisehealth/pit-viper/components/visualizations` |
|
|
36
|
-
| Dropdown (single select) | `PvSelectButton` | `@turquoisehealth/pit-viper/components` |
|
|
37
|
-
| Dropdown (multi select) | `PvMultiSelectButton` | `@turquoisehealth/pit-viper/components` |
|
|
38
|
-
| Modal or dialog | `PvModal` | `@turquoisehealth/pit-viper/components` |
|
|
39
|
-
| Side panel or drawer | `PvDrawer` | `@turquoisehealth/pit-viper/components` |
|
|
40
|
-
| Tabs | `PvTabs` | `@turquoisehealth/pit-viper/components` |
|
|
41
|
-
| Segmented control | `PvSegmentedControl` | `@turquoisehealth/pit-viper/components` |
|
|
42
|
-
| Search input | `PvSearchInput` | `@turquoisehealth/pit-viper/components` |
|
|
43
|
-
| Text input | `PvInput` | `@turquoisehealth/pit-viper/components` |
|
|
44
|
-
| Toggle or switch | `PvSwitch` | `@turquoisehealth/pit-viper/components` |
|
|
45
|
-
| Checkbox | `PvCheckbox` | `@turquoisehealth/pit-viper/components` |
|
|
46
|
-
| Button | `PvButton` | `@turquoisehealth/pit-viper/components` |
|
|
47
|
-
| Tag or badge | `PvTag` or `PvPill` | `@turquoisehealth/pit-viper/components` |
|
|
48
|
-
| Loading skeleton | `PvSkeleton` | `@turquoisehealth/pit-viper/components` |
|
|
49
|
-
| Spinner | `PvSpinner` | `@turquoisehealth/pit-viper/components` |
|
|
50
|
-
| Tooltip | `PvTooltipV2` | `@turquoisehealth/pit-viper/components` |
|
|
51
|
-
| Accordion | `PvAccordion` | `@turquoisehealth/pit-viper/components` |
|
|
52
|
-
| Breadcrumbs | `PvBreadcrumbs` | `@turquoisehealth/pit-viper/components` |
|
|
53
|
-
| Pagination | `PvPagination` | `@turquoisehealth/pit-viper/components` |
|
|
54
|
-
| Avatar | `PvAvatar` | `@turquoisehealth/pit-viper/components` |
|
|
55
|
-
| Icon | `PvIcon` | `@turquoisehealth/pit-viper/components` |
|
|
56
|
-
| Card | `PvCard` | `@turquoisehealth/pit-viper/components` |
|
|
57
|
-
| Banner or alert | `PvBanner` | `@turquoisehealth/pit-viper/components` |
|
|
58
|
-
| Toast notification | `PvToast` | `@turquoisehealth/pit-viper/components` |
|
|
59
|
-
| Progress bar | `PvProgressBar` | `@turquoisehealth/pit-viper/components` |
|
|
60
|
-
| Date picker | `PvDatePicker` | `@turquoisehealth/pit-viper/components` |
|
|
61
|
-
|
|
62
|
-
### 3. MCP Lookup (Preferred)
|
|
63
|
-
|
|
64
|
-
Use the Pit Viper MCP tools for fast, structured component data:
|
|
65
|
-
|
|
66
|
-
**For Vue components:**
|
|
67
|
-
1. Call `mcp__pit-viper__storybook_get_component` with the component name (e.g., "PvButton")
|
|
68
|
-
2. Returns: props, argTypes, stories, and source code
|
|
69
|
-
|
|
70
|
-
**For CSS components:**
|
|
71
|
-
1. Call `mcp__pit-viper__css_get_docs` with the component name (e.g., "buttons")
|
|
72
|
-
2. Returns: classes, documentation, and examples
|
|
73
|
-
|
|
74
|
-
**For general search:**
|
|
75
|
-
1. Call `mcp__pit-viper__search` with a query
|
|
76
|
-
2. Returns: matches across both CSS and Vue components
|
|
77
|
-
|
|
78
|
-
### 4. Plugin Examples (Fallback)
|
|
79
|
-
|
|
80
|
-
Check if a curated example exists in the plugin's `examples/` directory:
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
examples/{ComponentName}.vue
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
If found, read the file for usage patterns.
|
|
87
|
-
|
|
88
|
-
### 5. Storybook Web Lookup (Fallback)
|
|
89
|
-
|
|
90
|
-
If the component is identified but you need props and usage:
|
|
91
|
-
|
|
92
|
-
1. Fetch the Storybook index: `https://pit-viper-storybook.netlify.app/index.json`
|
|
93
|
-
2. Find the matching component story by name
|
|
94
|
-
3. Fetch docs page: `https://pit-viper-storybook.netlify.app/?path=/docs/{story-id}`
|
|
95
|
-
4. Extract props, variants, and code examples
|
|
96
|
-
|
|
97
|
-
### 6. Installed Package Types
|
|
98
|
-
|
|
99
|
-
If the project has `@turquoisehealth/pit-viper` installed, read type definitions for exact prop types:
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
node_modules/@turquoisehealth/pit-viper/pv-components/dist/vue/{ComponentName}.vue.d.ts
|
|
103
|
-
node_modules/@turquoisehealth/pit-viper/pv-components/dist/vue/{ComponentName}/types.d.ts
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## Output
|
|
107
|
-
|
|
108
|
-
Return a structured result:
|
|
109
|
-
|
|
110
|
-
```
|
|
111
|
-
## Component: PvSelectButton
|
|
112
|
-
|
|
113
|
-
**Import:**
|
|
114
|
-
import { PvSelectButton } from '@turquoisehealth/pit-viper/components'
|
|
115
|
-
|
|
116
|
-
**Key Props:**
|
|
117
|
-
- `v-model` — Selected value
|
|
118
|
-
- `options` — Array of { label, value } objects
|
|
119
|
-
- `optionsVariant` — 'default' | 'checkbox' | 'radio'
|
|
120
|
-
- `label` — Input label text
|
|
121
|
-
- `placeholder` — Placeholder when empty
|
|
122
|
-
- `searchable` — Enable search filtering (default: true)
|
|
123
|
-
|
|
124
|
-
**Usage Example:**
|
|
125
|
-
<PvSelectButton
|
|
126
|
-
v-model="selected"
|
|
127
|
-
:options="options"
|
|
128
|
-
label="Select an option"
|
|
129
|
-
placeholder="Choose..."
|
|
130
|
-
/>
|
|
131
|
-
|
|
132
|
-
**Confidence:** high (built-in mapping)
|
|
133
|
-
**Storybook:** https://pit-viper-storybook.netlify.app/?path=/docs/components-pvselect--docs
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## Confidence Levels
|
|
137
|
-
|
|
138
|
-
- **high** — Code Connect match or built-in mapping rule
|
|
139
|
-
- **medium** — Storybook match with clear props
|
|
140
|
-
- **low** — Best guess, recommend verification
|
|
141
|
-
|
|
142
|
-
If no matching Pit Viper component exists, say so explicitly and suggest the user check if it should be added to the design system.
|