@fragments-sdk/skills
Version:
Agent skills for Fragments — the design governance platform and UI component library
231 lines (184 loc) • 6.6 kB
Markdown
---
name: fragments/policy
description: Create and manage Fragments design policies from natural language descriptions. Use when the user wants to create a design rule, add a policy, enforce a convention, or customize governance checks.
type: core
library: "@fragments-sdk/govern"
library_version: ">=0.1.0"
sources:
- "fragments-sdk/skills:skills/policy/SKILL.md"
argument-hint: "[create|list|edit|delete] [description]"
---
# Fragments Policy
Create and manage custom design policies that Fragments enforces during governance checks.
## Prerequisites
- `@fragments-sdk/govern` and `@fragments-sdk/cli` must be installed. If not, run `/fragments-cloud-setup` first.
- A `fragments.config.ts` must exist. Ensure it includes a `policies` glob:
```ts
import { defineConfig } from '@fragments-sdk/govern';
export default defineConfig({
cloud: true,
checks: ['accessibility', 'consistency', 'responsive'],
policies: ['./.fragments/policies/*.ts'],
input: './src/**/*.{tsx,jsx}',
});
```
## Modes
Parse `$ARGUMENTS` to determine the mode:
- **create** (default): Create a new policy from a natural language description
- **list**: Show all active policies
- **edit**: Modify an existing policy
- **delete**: Remove a policy
## Create mode
1. Take the user's natural language description.
2. Generate a policy file in `.fragments/policies/`. Here are examples covering common categories:
**Touch target enforcement:**
```ts
// .fragments/policies/min-button-height.ts
import { definePolicy } from '@fragments-sdk/govern';
export default definePolicy({
name: 'min-button-height',
description: 'All buttons must have a minimum height of 44px for touch targets',
severity: 'error',
check({ node, report }) {
if (node.type === 'button' || node.role === 'button') {
const height = node.computedStyles?.height;
if (height && parseFloat(height) < 44) {
report({
message: `Button height is ${height} but minimum is 44px`,
fix: { property: 'minHeight', value: '44px' },
});
}
}
},
});
```
**Design token enforcement:**
```ts
// .fragments/policies/no-hardcoded-colors.ts
import { definePolicy } from '@fragments-sdk/govern';
export default definePolicy({
name: 'no-hardcoded-colors',
description: 'Colors must use design tokens, not raw hex/rgb values',
severity: 'warning',
check({ node, report }) {
const colorProps = ['color', 'backgroundColor', 'borderColor'];
for (const prop of colorProps) {
const value = node.styles?.[prop];
if (value && /^(#|rgb|hsl)/.test(value)) {
report({
message: `Hardcoded color "${value}" on "${prop}" -- use a design token instead`,
fix: { property: prop, value: 'var(--fui-text-primary)' },
});
}
}
},
});
```
**Structural accessibility:**
```ts
// .fragments/policies/single-h1.ts
import { definePolicy } from '@fragments-sdk/govern';
export default definePolicy({
name: 'single-h1',
description: 'Each page must have exactly one h1 element',
severity: 'error',
check({ node, context, report }) {
if (node.tag === 'h1') {
context.h1Count = (context.h1Count || 0) + 1;
if (context.h1Count > 1) {
report({
message: `Multiple h1 elements found (this is #${context.h1Count}). Use h2-h6 for subheadings.`,
});
}
}
},
});
```
3. Register the policy -- ensure `fragments.config.ts` has a `policies` glob that matches the new file path.
4. Run a check to validate: `npx fragments govern check --cloud`
5. Show results and ask if the policy needs adjustment.
## List mode
```bash
npx fragments govern policies list
```
If the CLI subcommand is not available, read all files in `.fragments/policies/` directly and display: policy name, description, severity, status (active/disabled).
## Edit mode
1. If no policy name is specified, show the list first.
2. Read the target policy file in `.fragments/policies/`.
3. Let the user describe the change in natural language.
4. Update the policy file and re-run checks to validate:
```bash
npx fragments govern check --cloud
```
## Delete mode
1. If no policy name is specified, show the list first.
2. Confirm with the user before deleting.
3. Remove the policy file from `.fragments/policies/`.
4. Remove its reference from `fragments.config.ts` if individually listed (not needed if using a glob pattern).
5. Confirm deletion.
## Common mistakes
### CRITICAL: Policy exists but never runs
Forgetting to add the `policies` glob in `fragments.config.ts`. The file sits on disk but the governance engine never loads it.
Wrong -- no `policies` field:
```ts
import { defineConfig } from '@fragments-sdk/govern';
export default defineConfig({
cloud: true,
checks: ['accessibility', 'consistency'],
input: './src/**/*.{tsx,jsx}',
});
```
Correct -- `policies` glob included:
```ts
import { defineConfig } from '@fragments-sdk/govern';
export default defineConfig({
cloud: true,
checks: ['accessibility', 'consistency'],
policies: ['./.fragments/policies/*.ts'],
input: './src/**/*.{tsx,jsx}',
});
```
### HIGH: Multi-concern policy
Bundling unrelated checks into one policy makes it impossible to disable a single rule without losing the others.
Wrong -- one policy checking touch targets, colors, and headings:
```ts
export default definePolicy({
name: 'ui-standards',
severity: 'error',
check({ node, report }) {
if (node.type === 'button' && parseFloat(node.computedStyles?.height) < 44) {
report({ message: 'Button too small' });
}
if (node.styles?.color && /^#/.test(node.styles.color)) {
report({ message: 'Hardcoded color' });
}
},
});
```
Correct -- split into `min-button-height.ts` and `no-hardcoded-colors.ts` with one concern each.
### MEDIUM: `error` severity for style preferences
`error` severity fails CI pipelines. Reserve it for accessibility and functional issues. Use `warning` for stylistic guidance.
Wrong:
```ts
export default definePolicy({
name: 'prefer-semibold',
description: 'Headings should use semibold weight',
severity: 'error',
// ...
});
```
Correct:
```ts
export default definePolicy({
name: 'prefer-semibold',
description: 'Headings should use semibold weight',
severity: 'warning',
// ...
});
```
## Guidelines
- Default severity to `warning` unless explicitly requested as `error`
- Always include a human-readable `description`
- Include an auto-fix in the `fix` field when possible
- Use kebab-case for policy file names
- One concern per policy -- keep logic focused