gql:guide
Interactive guide to soda-gql features and patterns
Best use case
gql:guide is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Interactive guide to soda-gql features and patterns
Teams using gql:guide should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/gql-guide/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How gql:guide Compares
| Feature / Agent | gql:guide | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Interactive guide to soda-gql features and patterns
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# GraphQL Guide Skill
This skill provides interactive guidance on soda-gql features, syntax patterns, and best practices. Use `$ARGUMENTS` to route to specific topics, or ask the user to choose a topic.
## Topic Routing
Parse `$ARGUMENTS` to determine the user's intent, or use AskUserQuestion to offer topic selection.
### Available Topics
1. **tagged-template** — Tagged template syntax for fragments and operations
2. **fragment** — Fragment definitions and spreading patterns
3. **operation** — Query, mutation, and subscription operations
4. **union** — Union type handling and member selection
5. **directive** — GraphQL directives (@include, @skip, custom directives)
6. **metadata** — Fragment metadata and field-level callbacks
7. **setup** — Project setup, config, and initial codegen
8. **lsp** — LSP integration, editor setup, and diagnostics
9. **codegen** — Schema codegen, typegen, and build integration
10. **colocation** — Fragment colocation patterns ($colocate directive)
### Topic Selection
If `$ARGUMENTS` is empty or unclear, use AskUserQuestion:
**Question:** "What would you like guidance on?"
**Options:**
- "Tagged template syntax" → tagged-template
- "Fragment patterns" → fragment
- "Operations (queries/mutations)" → operation
- "Union types" → union
- "Directives" → directive
- "Metadata and callbacks" → metadata
- "Project setup" → setup
- "LSP and editor integration" → lsp
- "Codegen and build tools" → codegen
- "Fragment colocation" → colocation
## Topic Content
For each topic, provide:
1. Concept explanation
2. References to documentation files
3. Code examples from playground
4. Common patterns and anti-patterns
5. Related topics
---
## Topic 1: tagged-template
### Concept
soda-gql supports tagged template syntax for writing GraphQL fragments and operations. Only `gql` is exported from the generated runtime:
```typescript
import { gql } from "<outdir-path>"; // e.g. "@/graphql-system"
// Fragment with tagged template
const userFragment = gql.default(({ fragment }) =>
fragment("UserFields", "User")`{
id
name
email
}`(),
);
// Operation with tagged template
const getUserQuery = gql.default(({ query }) =>
query("GetUser")`($id: ID!) {
user(id: $id) {
id
name
}
}`(),
);
```
### When to Use Tagged Template vs Callback Builder
**Decision Tree:**
1. **Fragment definition:**
- ✅ Use tagged template: Simple field selection, no aliases
- ❌ Use callback builder: Field aliases needed
2. **Fragment spreading (Fragment → Fragment):**
- ✅ Use tagged template interpolation: `...${otherFragment}`
3. **Operation definition:**
- ✅ Use tagged template: No fragment spreads via `.spread()`, no aliases, no $colocate
- ❌ Use callback builder: Has fragment spreads via `.spread()`, aliases, or $colocate
4. **Special features:**
- Metadata callbacks with variable access → callback builder only
- Operations with `.spread()` → callback builder only
### Key Constraint
**Both tagged templates reject interpolation with values:**
- `fragment("Name", "Type")\`${value}\`` → ❌ Throws error
- `query("Name")\`{ field(id: ${id}) }\`` → ❌ Throws error
The only valid interpolation is fragment-to-fragment spreading: `fragment("Name", "Type")\`...${otherFragment} ...\``.
Operations with fragment spreads MUST use callback builder syntax with `.spread()` instead of tagged template interpolation.
### Documentation References
- **Callback-only features:** `playgrounds/vite-react/src/graphql/callback-builder-features.ts`
- **Fragment patterns:** `playgrounds/vite-react/src/graphql/fragment-spread-patterns.md`
### Code Examples
**Tagged template fragment:**
```typescript
// playgrounds/vite-react/src/graphql/fragments.ts
const userFields = gql.default(({ fragment }) =>
fragment("UserFields", "User")`{
id
name
email
createdAt
}`(),
);
```
**Tagged template operation (no spreads):**
```typescript
// playgrounds/vite-react/src/graphql/operations.ts
const simpleQuery = gql.default(({ query }) =>
query("GetUsers")`{
users {
id
name
}
}`(),
);
```
**Callback builder operation (with spreads):**
```typescript
// playgrounds/vite-react/src/graphql/callback-builder-features.ts
const userQuery = gql.default(({ query, $var }) =>
query.operation({
name: "GetUser",
variables: {
...$var("id").ID("!"),
},
fields: ({ f, $ }) => ({
...f.user({ id: $.id })(({ f }) => ({
...userFields.spread(),
})),
}),
}),
);
```
### Common Patterns
✅ **Simple fragment with tagged template:**
```typescript
const fields = gql.default(({ fragment }) =>
fragment("UserBasic", "User")`{
id
name
email
}`(),
);
```
✅ **Fragment spreading another fragment (tagged template):**
```typescript
const extendedFields = gql.default(({ fragment }) =>
fragment("ExtendedUser", "User")`{
...${userFields}
createdAt
updatedAt
}`(),
);
```
❌ **Operation with fragment spread (WRONG - tagged template):**
```typescript
// This will FAIL - cannot use tagged template interpolation for fragment spreads in operations
const badQuery = gql.default(({ query }) =>
query("BadQuery")`{
user {
${userFields}
}
}`(),
);
```
✅ **Operation with fragment spread (CORRECT - callback builder):**
```typescript
const userQuery = gql.default(({ query, $var }) =>
query.operation({
name: "GetUser",
variables: { ...$var("id").ID("!") },
fields: ({ f, $ }) => ({
...f.user({ id: $.id })(({ f }) => ({
...userFields.spread(),
})),
}),
}),
);
```
### Related Topics
- **fragment** — Fragment definition and spreading patterns
- **operation** — Operation structure and variable handling
- **metadata** — Callback-builder-only metadata feature
---
## Topic 2: fragment
### Concept
Fragments define reusable field selections with type safety. They can be spread into operations or composed into other fragments.
### Fragment Types
1. **Tagged template fragment** — Simple field selection
2. **Callback builder fragment** — Aliases, nested spreads, metadata
3. **Fragment spreading** — Composing fragments together
### Variable Declaration Pattern
**"Fragments declare requirements; operations declare contract"**
- Fragments can declare variables they need in the GraphQL definition
- Operations must explicitly declare ALL variables, including fragment requirements
- No auto-merge: operation variables are the source of truth
### Documentation References
- **Spread patterns:** `playgrounds/vite-react/src/graphql/fragment-spread-patterns.md`
- **Nested spreads:** `playgrounds/vite-react/src/graphql/nested-fragment-verification.ts`
### Code Examples
**Simple fragment:**
```typescript
const userBasic = gql.default(({ fragment }) =>
fragment("UserBasic", "User")`{
id
name
email
}`(),
);
```
**Fragment with variables:**
```typescript
const userConditional = gql.default(({ fragment }) =>
fragment("ConditionalUser", "User")`($includeEmail: Boolean!) {
id
name
email @include(if: $includeEmail)
}`(),
);
```
**Fragment spreading (Fragment → Fragment):**
```typescript
const userExtended = gql.default(({ fragment }) =>
fragment("ExtendedUser", "User")`{
...${userBasic}
createdAt
updatedAt
}`(),
);
```
**Operation spreading fragment (callback builder):**
```typescript
const getUserQuery = gql.default(({ query, $var }) =>
query.operation({
name: "GetUser",
variables: {
...$var("id").ID("!"),
...$var("includeEmail").Boolean("!"),
},
fields: ({ f, $ }) => ({
...f.user({ id: $.id })(({ f }) => ({
...userConditional.spread({ includeEmail: $.includeEmail }),
})),
}),
}),
);
```
### Common Patterns
✅ **Fragment composition via tagged template:**
```typescript
const baseFields = gql.default(({ fragment }) =>
fragment("UserBase", "User")`{ id name }`(),
);
const extendedFields = gql.default(({ fragment }) =>
fragment("UserExtended", "User")`{
...${baseFields}
email
}`(),
);
```
✅ **Operation declares all variables:**
```typescript
const getUserQuery = gql.default(({ query, $var }) =>
query.operation({
name: "GetUser",
variables: {
...$var("id").ID("!"),
...$var("includeEmail").Boolean("!"), // ALL variables, including fragment requirements
},
fields: ({ f, $ }) => ({
...f.user({ id: $.id })(({ f }) => ({
...userConditional.spread({ includeEmail: $.includeEmail }),
})),
}),
}),
);
```
❌ **Auto-merge expectation (WRONG):**
```typescript
// Fragment declares $includeEmail
const frag = gql.default(({ fragment }) =>
fragment("F", "User")`($includeEmail: Boolean!) {
id name email @include(if: $includeEmail)
}`(),
);
// Operation does NOT auto-inherit variables — must declare includeEmail explicitly
const badQuery = gql.default(({ query, $var }) =>
query.operation({
name: "GetUser",
variables: { ...$var("id").ID("!") }, // Missing includeEmail!
fields: ({ f, $ }) => ({
...f.user({ id: $.id })(({ f }) => ({
...frag.spread(), // Will fail — $includeEmail not in scope
})),
}),
}),
);
```
### Related Topics
- **tagged-template** — Syntax for fragment definitions
- **operation** — How operations use fragments
- **metadata** — Fragment-level metadata callbacks
---
## Topic 3: operation
### Concept
Operations define the GraphQL query/mutation/subscription structure with variables, arguments, and field selections.
### Operation Types
1. **Tagged template operation** — Simple operations without fragment spreads
2. **Callback builder operation** — Complex operations with spreads, aliases, $colocate
### Variable Handling
**Operations declare the contract:**
- All variables must be declared at operation level
- Fragment variables are NOT auto-merged
- In callback builder, use `$var("name").Type("!")` to declare variables
### Documentation References
- **Examples:** `playgrounds/vite-react/src/graphql/operations.ts`
- **Callback-only features:** `playgrounds/vite-react/src/graphql/callback-builder-features.ts`
### Code Examples
**Simple query (tagged template):**
```typescript
const getUsers = gql.default(({ query }) =>
query("GetUsers")`{
users {
id
name
}
}`(),
);
```
**Query with variables (tagged template):**
```typescript
const getUser = gql.default(({ query }) =>
query("GetUser")`($id: ID!) {
user(id: $id) {
id
name
email
}
}`(),
);
```
**Query with fragment spread (callback builder):**
```typescript
const getUserWithFragment = gql.default(({ query, $var }) =>
query.operation({
name: "GetUserWithFragment",
variables: {
...$var("id").ID("!"),
},
fields: ({ f, $ }) => ({
...f.user({ id: $.id })(({ f }) => ({
...userFields.spread(),
})),
}),
}),
);
```
**Mutation (tagged template):**
```typescript
const createUser = gql.default(({ mutation }) =>
mutation("CreateUser")`($input: CreateUserInput!) {
createUser(input: $input) {
id
name
}
}`(),
);
```
### Common Patterns
✅ **Simple query (tagged template):**
```typescript
const getUserQuery = gql.default(({ query }) =>
query("GetUser")`($id: ID!) {
user(id: $id) {
id
name
posts {
id
title
}
}
}`(),
);
```
✅ **Operation with multiple variables (callback builder):**
```typescript
const getUserPosts = gql.default(({ query, $var }) =>
query.operation({
name: "GetUserPosts",
variables: {
...$var("id").ID("!"),
...$var("limit").Int(),
...$var("offset").Int(),
},
fields: ({ f, $ }) => ({
...f.user({ id: $.id })(({ f }) => ({
...f.posts({ limit: $.limit, offset: $.offset })(({ f }) => ({
id: f.id,
title: f.title,
})),
})),
}),
}),
);
```
### Related Topics
- **tagged-template** — Operation syntax options
- **fragment** — Using fragments in operations
- **directive** — Adding directives to operations
---
## Topic 4: union
### Concept
Union types in GraphQL represent a value that could be one of several types. soda-gql handles union types using standard GraphQL inline fragment syntax in tagged templates.
### Union Member Selection
Union handling uses standard GraphQL inline fragment syntax (`... on TypeName { fields }`). Always include `__typename` for type discrimination:
```typescript
const searchQuery = gql.default(({ query }) =>
query("Search")`($term: String!) {
search(term: $term) {
__typename
... on User {
id
name
}
... on Organization {
id
name
members
}
}
}`(),
);
```
### Documentation References
- **Union verification:** `playgrounds/vite-react/src/graphql/union-type-verification.ts`
- **Callback-only features:** `playgrounds/vite-react/src/graphql/callback-builder-features.ts`
### Code Examples
**Union field selection (tagged template):**
```typescript
const searchQuery = gql.default(({ query }) =>
query("Search")`($term: String!) {
search(term: $term) {
__typename
... on User {
id
name
email
}
... on Post {
id
title
content
}
}
}`(),
);
```
**Union with fragment spread (callback builder):**
```typescript
const userFields = gql.default(({ fragment }) =>
fragment("UserFields", "User")`{ id name email }`(),
);
const postFields = gql.default(({ fragment }) =>
fragment("PostFields", "Post")`{ id title content }`(),
);
const searchQuery = gql.default(({ query, $var }) =>
query.operation({
name: "Search",
variables: { ...$var("term").String("!") },
fields: ({ f, $ }) => ({
...f.search({ term: $.term })(({ f }) => ({
__typename: f.__typename,
...userFields.spread(),
...postFields.spread(),
})),
}),
}),
);
```
### Common Patterns
✅ **Always include __typename:**
```typescript
const q = gql.default(({ query }) =>
query("Search")`($term: String!) {
search(term: $term) {
__typename
... on TypeA { id fieldA }
... on TypeB { id fieldB }
}
}`(),
);
```
✅ **Exhaustive member handling:**
```typescript
const q = gql.default(({ query }) =>
query("SearchAll")`($term: String!) {
search(term: $term) {
__typename
... on User { id name }
... on Organization { id name }
... on Bot { id label }
}
}`(),
);
```
### Related Topics
- **fragment** — Using fragments with union members
- **metadata** — Type-specific metadata callbacks
---
## Topic 5: directive
### Concept
GraphQL directives modify field behavior (@include, @skip) or provide metadata for tools. soda-gql supports standard and custom directives.
### Directive Types
1. **Standard directives:** `@include(if: Boolean)`, `@skip(if: Boolean)`
2. **Custom directives:** Defined in schema, used for metadata or tooling
### Directive Syntax
**Tagged template with static values:**
```typescript
gql.default(({ fragment }) =>
fragment("UserFields", "User")`{
id
name
email @include(if: true)
}`(),
);
```
**Tagged template with variables:**
```typescript
gql.default(({ fragment }) =>
fragment("ConditionalUser", "User")`($includeEmail: Boolean!) {
id
name
email @include(if: $includeEmail)
}`(),
);
```
### Documentation References
- **Directive verification:** `playgrounds/vite-react/src/graphql/directive-verification.ts`
### Code Examples
**@include directive:**
```typescript
const conditionalFields = gql.default(({ fragment }) =>
fragment("ConditionalUser", "User")`($showEmail: Boolean!) {
id
name
email @include(if: $showEmail)
}`(),
);
```
**@skip directive:**
```typescript
const fields = gql.default(({ fragment }) =>
fragment("SkipEmail", "User")`($hideEmail: Boolean!) {
id
name
email @skip(if: $hideEmail)
}`(),
);
```
**Custom directive:**
```typescript
// Assuming schema has: directive @sensitive on FIELD_DEFINITION
const userFields = gql.default(({ fragment }) =>
fragment("SensitiveUser", "User")`{
id
name
socialSecurityNumber @sensitive
}`(),
);
```
### Common Patterns
✅ **Conditional field inclusion (callback builder with fragment spread):**
```typescript
const detailsFragment = gql.default(({ fragment }) =>
fragment("UserDetails", "User")`($includeDetails: Boolean!) {
bio @include(if: $includeDetails)
website @include(if: $includeDetails)
}`(),
);
const getUserQuery = gql.default(({ query, $var }) =>
query.operation({
name: "GetUser",
variables: {
...$var("id").ID("!"),
...$var("includeDetails").Boolean("!"),
},
fields: ({ f, $ }) => ({
...f.user({ id: $.id })(({ f }) => ({
id: f.id,
name: f.name,
...detailsFragment.spread({ includeDetails: $.includeDetails }),
})),
}),
}),
);
```
### Related Topics
- **fragment** — Directives in fragment definitions
- **metadata** — Directive metadata for tooling
---
## Topic 6: metadata
### Concept
soda-gql allows attaching metadata to fragments and operations for build-time processing (e.g., component mapping, documentation generation). Metadata is passed as an argument to the template call.
### Metadata APIs
**Static metadata** — passed as argument to the template call:
```typescript
const frag = gql.default(({ fragment }) =>
fragment("UserFields", "User")`{
id
name
}`({
metadata: { component: "UserCard" },
}),
);
```
**Callback metadata** — receives variables for dynamic values:
```typescript
const frag = gql.default(({ fragment }) =>
fragment("UserFields", "User")`($userId: ID!) {
id
name
}`({
metadata: ({ $ }: { $: { userId: string } }) => ({
cacheKey: `user:${$.userId}`,
}),
}),
);
```
### Documentation References
- **Callback-only features:** `playgrounds/vite-react/src/graphql/callback-builder-features.ts`
- **Metadata verification:** `playgrounds/vite-react/src/graphql/metadata-verification.ts`
### Code Examples
**Static fragment metadata:**
```typescript
const userFragment = gql.default(({ fragment }) =>
fragment("UserCard", "User")`{
id
name
email
}`({
metadata: { component: "UserCard", description: "User profile data" },
}),
);
```
**Callback metadata with variables:**
```typescript
const userFragment = gql.default(({ fragment }) =>
fragment("CachedUser", "User")`($userId: ID!) {
id
name
email
}`({
metadata: ({ $ }: { $: { userId: string } }) => ({
cacheKey: `user:${$.userId}`,
}),
}),
);
```
**Callback builder operation with metadata:**
```typescript
const q = gql.default(({ query, $var }) =>
query.operation({
name: "GetUser",
variables: { ...$var("id").ID("!") },
metadata: ({ $, fragmentMetadata }) => ({
entityId: $.id,
fragmentCount: fragmentMetadata?.length ?? 0,
}),
fields: ({ f, $ }) => ({
...f.user({ id: $.id })(({ f }) => ({
...userFragment.spread(),
})),
}),
}),
);
```
### Common Patterns
✅ **Component mapping:**
```typescript
gql.default(({ fragment }) =>
fragment("UserProfile", "User")`{ id name }`({
metadata: { component: "UserProfile" },
}),
);
```
✅ **Dynamic cache key:**
```typescript
gql.default(({ fragment }) =>
fragment("CachedUser", "User")`($id: ID!) { id name }`({
metadata: ({ $ }: { $: { id: string } }) => ({
cacheKey: `user:${$.id}`,
}),
}),
);
```
### Related Topics
- **fragment** — Metadata on fragments
- **colocation** — $colocate with metadata
---
## Topic 7: setup
### Concept
Setting up a new soda-gql project involves config file creation, schema setup, and initial codegen.
### Setup Steps
1. **Install dependencies:**
```bash
bun add @soda-gql/core @soda-gql/builder
bun add -d @soda-gql/cli
```
2. **Add framework plugin (optional but recommended):**
```bash
# For Vite
bun add -d @soda-gql/vite-plugin
# For Next.js
bun add -d @soda-gql/next-plugin
```
3. **Create config file (`soda-gql.config.ts`):**
```typescript
import { defineConfig } from '@soda-gql/config';
export default defineConfig({
outdir: './src/graphql/generated',
schemas: {
default: {
schemaFiles: ['./schema.graphql'],
},
},
});
```
4. **Run initial codegen:**
```bash
bun run soda-gql codegen schema
```
5. **Configure build plugin (Vite example):**
```typescript
// vite.config.ts
import { sodaGql } from '@soda-gql/vite-plugin';
export default {
plugins: [sodaGql()],
};
```
### Documentation References
- **Main README:** `README.md` — Installation and quick start
- **Playground examples:** `playgrounds/vite-react/src/graphql/` — Working examples of all features
### Common Issues
**Issue: codegen fails with "config not found"**
- Check config file is named correctly: `soda-gql.config.{ts,js,mjs}`
- Check config exports with `export default`
**Issue: "Cannot find module '@soda-gql/core'"**
- Run `bun install` to install dependencies
- Check package.json includes @soda-gql packages
**Issue: Types not updating in editor**
- Restart TypeScript server
- Check outdir matches tsconfig include paths
### Related Topics
- **codegen** — Running codegen and typegen
- **lsp** — Editor integration
---
## Topic 8: lsp
### Concept
soda-gql provides LSP (Language Server Protocol) integration for real-time diagnostics, autocomplete, and hover information in editors.
### LSP Features
1. **Real-time diagnostics:** Type errors, invalid fields, syntax errors
2. **Autocomplete:** Field names, types, directives
3. **Hover information:** Type info, documentation
4. **Go to definition:** Jump to schema type definitions
### Editor Setup
**VS Code:**
1. Install LSP extension (if available)
2. Configure workspace settings:
```json
{
"soda-gql.configPath": "./soda-gql.config.ts"
}
```
**Other editors:**
- Use language server client compatible with your editor
- Point to soda-gql LSP server
### LSP Diagnostics
The LSP validates:
- Field existence on types
- Argument types and required args
- Fragment type compatibility
- Variable types
- Directive usage
### Common Issues
**Issue: LSP not providing diagnostics**
- Check config file is found (`found: true` in project detection)
- Restart editor/LSP server
- Check LSP logs for errors
**Issue: False positive errors**
- Run `bun run soda-gql codegen schema` to sync generated types
- Check schema files are up to date
### Related Topics
- **setup** — Initial LSP configuration
- **codegen** — Keeping LSP in sync with schema
---
## Topic 9: codegen
### Concept
soda-gql codegen generates TypeScript types from GraphQL schemas (schema codegen) and validates/generates types from tagged templates (typegen).
### Codegen Commands
1. **Schema codegen:**
```bash
bun run soda-gql codegen schema
```
- Reads schema files from config
- Generates runtime type system in outdir
- Creates fragment and query builder types
2. **Type generation (typegen):**
```bash
bun run soda-gql typegen
```
- Scans codebase for tagged templates
- Validates field selections against schema
- Generates TypeScript types for fragments/operations
### Build Integration
**Development workflow:**
1. Edit schema files
2. Run `bun run soda-gql codegen schema`
3. Edit fragments/operations
4. Build plugin auto-runs typegen during build
**Watch mode (if supported):**
```bash
bun run soda-gql codegen schema --watch
```
### Documentation References
- **Monorepo infrastructure:** `docs/guides/monorepo-infrastructure.md` — Build system
### Common Issues
**Issue: "Schema file not found"**
- Check schemaFiles paths in config are relative to config file
- Use Read tool to verify file exists at expected path
**Issue: Typegen shows "unknown field"**
- Run schema codegen first: `bun run soda-gql codegen schema`
- Check field name spelling matches schema
**Issue: Generated types not updating**
- Delete generated directory and re-run codegen
- Check outdir in config matches import paths
### Related Topics
- **setup** — Initial codegen configuration
- **lsp** — Real-time validation vs build-time codegen
---
## Topic 10: colocation
### Concept
Fragment colocation places fragment definitions near the components that use them, improving code organization and enabling build-time optimizations.
### Colocation Patterns
**$colocate in callback builder spread:**
```typescript
const userQuery = gql.default(({ query, $var }) =>
query.operation({
name: "GetUser",
variables: { ...$var("id").ID("!") },
fields: ({ f, $ }) => ({
...f.user({ id: $.id })(({ f }) => ({
id: f.id,
...userFragment.spread({ $colocate: true }),
})),
}),
}),
);
```
**Component colocation:**
```typescript
// UserCard.tsx
export const userCardFragment = gql.default(({ fragment }) =>
fragment("UserCardFields", "User")`{
id
name
email
avatarUrl
}`(),
);
export function UserCard({ user }) {
// Component uses fragment data
}
```
### Build-Time Processing
Colocation enables:
- Dead code elimination (unused fragments removed)
- Component-fragment association tracking
- Automatic fragment composition
### Documentation References
- **Callback-only features:** `playgrounds/vite-react/src/graphql/callback-builder-features.ts` — $colocate examples
### Common Patterns
✅ **Component-fragment pair:**
```typescript
// UserProfile.tsx
const userProfileFragment = gql.default(({ fragment }) =>
fragment("UserProfile", "User")`{
id
name
email
bio
}`(),
);
function UserProfile({ data }) {
// Use fragment data
}
```
✅ **Fragment composition with colocation:**
```typescript
const parentQuery = gql.default(({ query, $var }) =>
query.operation({
name: "GetUserPage",
variables: { ...$var("id").ID("!") },
fields: ({ f, $ }) => ({
...f.user({ id: $.id })(({ f }) => ({
...profileFragment.spread({ $colocate: true }),
...settingsFragment.spread({ $colocate: true }),
})),
}),
}),
);
```
### Related Topics
- **fragment** — Fragment spreading and composition
- **metadata** — Component metadata with colocation
---
## Interactive Mode
If the user's question doesn't match a specific topic, use Grep to search documentation:
1. Extract keywords from user's question
2. Use Grep to search docs/guides/ and playgrounds/
3. Read matching files and synthesize answer
4. Reference specific documentation sections
### Example: User asks "How do I add pagination?"
1. Grep for "pagination" in docs and playground
2. If not found, explain general approach:
- Add limit/offset arguments to field
- Use variables in operation
- Show example with args
3. Suggest related topics: operation, fragment
## Validation Checklist
Before completing this skill, ensure:
- ✅ Topic was identified from $ARGUMENTS or user selection
- ✅ Relevant documentation was referenced
- ✅ Code examples were provided from playground or synthesized
- ✅ Common patterns and anti-patterns were shown
- ✅ Related topics were suggested for further explorationRelated Skills
workflow-guide
Provides guidance on Cursor ↔ Claude Code 2-agent workflow. Use when user mentions ワークフローについて, Cursorとの連携, 作業の流れ, 2-agent workflow, collaboration. Do NOT load for: 実装作業, ワークフロー設定, ハンドオフ実行.
validate-guidelines
Empirically verify guideline changes by running before/after eval runs across multiple models and ensuring no regressions. Use when proposing or reviewing changes to runner/models/guidelines.ts, or when the user asks to validate guidelines.
service-guide
Guide for implementing Backend.AI service layer (create, get, search, update, delete, purge, batch operations, Actions, ActionResults, Processors, ActionProcessor, Service methods)
Plexus Classifier Guidelines Management
The format for guidelines documents for Plexus scorecard scores and the validation tool.
migration-guides
Migration guides - from other AI tools, version upgrades, config migration. Use when switching from Cursor, Copilot, or Cody, upgrading Claude Code versions, or migrating configurations and customizations.
implementation-guide
Generate comprehensive implementation guides for coding tasks instead of writing code directly. Use when the user requests detailed implementation documentation, step-by-step development guides, or when they want to implement features themselves using tools like Cursor. Creates exhaustive guides with background context, architecture decisions, milestones with verification points, and rationale for a "build-it-yourself" workflow.
guided-debugging
Scaffolded debugging guidance for learning. Use when a learner encounters unexpected behavior, errors, or bugs and wants to develop debugging skills, not just fix the problem. This skill guides through hypothesis formation, investigation design, and root cause analysis while enforcing human-only decision points. Triggers on phrases like "help me debug", "something's wrong with my code", "unexpected behavior", "learning to debug", or when a learner describes symptoms without immediately asking for the fix.
github.com/n-r-w/ctxlog guidelines
Guidelines and examples for using the ctxlog logging package.
environment-setup-guide
Guide developers through setting up development environments with proper tools, dependencies, and configurations
ecosystem-guide
Guide to spences10's Claude Code ecosystem. Use when user asks which tool to use, how tools relate, or needs help choosing between MCP servers, skills, or CLIs.
cowork-guide
CRITICAL: Comprehensive guide for CoWork Skills CLI tool. Triggers on: cowork, Skills.toml, skill management, plugin configuration, cowork init, cowork install, cowork config, cowork generate
components-guide
Guide to using Convex components for feature encapsulation. Learn about sibling components, creating your own, and when to use components vs monolithic code.