Skip to content

Commit 0fe1cdd

Browse files
committed
improvement(skills): add typed JSON outputs guidance to add-tools, add-block, and add-integration skills
1 parent ca91ce8 commit 0fe1cdd

File tree

3 files changed

+52
-2
lines changed

3 files changed

+52
-2
lines changed

.claude/commands/add-block.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,41 @@ outputs: {
532532
}
533533
```
534534

535+
### Typed JSON Outputs
536+
537+
When using `type: 'json'` and you know the object shape in advance, **describe the inner fields in the description** so downstream blocks know what properties are available. For well-known, stable objects, use nested output definitions instead:
538+
539+
```typescript
540+
outputs: {
541+
// BAD: Opaque json with no info about what's inside
542+
plan: { type: 'json', description: 'Zone plan information' },
543+
544+
// GOOD: Describe the known fields in the description
545+
plan: {
546+
type: 'json',
547+
description: 'Zone plan information (id, name, price, currency, frequency, is_subscribed)',
548+
},
549+
550+
// BEST: Use nested output definition when the shape is stable and well-known
551+
plan: {
552+
id: { type: 'string', description: 'Plan identifier' },
553+
name: { type: 'string', description: 'Plan name' },
554+
price: { type: 'number', description: 'Plan price' },
555+
currency: { type: 'string', description: 'Price currency' },
556+
},
557+
}
558+
```
559+
560+
Use the nested pattern when:
561+
- The object has a small, stable set of fields (< 10)
562+
- Downstream blocks will commonly access specific properties
563+
- The API response shape is well-documented and unlikely to change
564+
565+
Use `type: 'json'` with a descriptive string when:
566+
- The object has many fields or a dynamic shape
567+
- It represents a list/array of items
568+
- The shape varies by operation
569+
535570
## V2 Block Pattern
536571

537572
When creating V2 blocks (alongside legacy V1):

.claude/commands/add-integration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ export const {service}{Action}Tool: ToolConfig<Params, Response> = {
102102
- Always use `?? []` for optional array fields
103103
- Set `optional: true` for outputs that may not exist
104104
- Never output raw JSON dumps - extract meaningful fields
105+
- When using `type: 'json'` and you know the object shape, define `properties` with the inner fields so downstream consumers know the structure. Only use bare `type: 'json'` when the shape is truly dynamic
105106

106107
## Step 3: Create Block
107108

.claude/commands/add-tools.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,18 @@ closedAt: {
147147
},
148148
```
149149

150-
### Nested Properties
151-
For complex outputs, define nested structure:
150+
### Typed JSON Outputs
151+
152+
When using `type: 'json'` and you know the object shape in advance, **always define the inner structure** using `properties` so downstream consumers know what fields are available:
153+
152154
```typescript
155+
// BAD: Opaque json with no info about what's inside
156+
metadata: {
157+
type: 'json',
158+
description: 'Response metadata',
159+
},
160+
161+
// GOOD: Define the known properties
153162
metadata: {
154163
type: 'json',
155164
description: 'Response metadata',
@@ -159,7 +168,10 @@ metadata: {
159168
count: { type: 'number', description: 'Total count' },
160169
},
161170
},
171+
```
162172

173+
For arrays of objects, define the item structure:
174+
```typescript
163175
items: {
164176
type: 'array',
165177
description: 'List of items',
@@ -173,6 +185,8 @@ items: {
173185
},
174186
```
175187

188+
Only use bare `type: 'json'` without `properties` when the shape is truly dynamic or unknown.
189+
176190
## Critical Rules for transformResponse
177191

178192
### Handle Nullable Fields

0 commit comments

Comments
 (0)