You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .claude/commands/add-block.md
+108-2Lines changed: 108 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -532,6 +532,41 @@ outputs: {
532
532
}
533
533
```
534
534
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
mode: 'advanced', // Rarely used, hide from basic view
751
+
}
752
+
```
753
+
754
+
## WandConfig for Complex Inputs
755
+
756
+
Use `wandConfig` for fields that are hard to fill out manually, such as timestamps, comma-separated lists, and complex query strings. This gives users an AI-assisted input experience.
757
+
758
+
```typescript
759
+
// Timestamps - use generationType: 'timestamp' to inject current date context
760
+
{
761
+
id: 'startTime',
762
+
title: 'Start Time',
763
+
type: 'short-input',
764
+
mode: 'advanced',
765
+
wandConfig: {
766
+
enabled: true,
767
+
prompt: 'Generate an ISO 8601 timestamp based on the user description. Return ONLY the timestamp string.',
768
+
generationType: 'timestamp',
769
+
},
770
+
}
771
+
772
+
// Comma-separated lists - simple prompt without generationType
773
+
{
774
+
id: 'mediaIds',
775
+
title: 'Media IDs',
776
+
type: 'short-input',
777
+
mode: 'advanced',
778
+
wandConfig: {
779
+
enabled: true,
780
+
prompt: 'Generate a comma-separated list of media IDs. Return ONLY the comma-separated values.',
781
+
},
782
+
}
783
+
```
784
+
785
+
## Naming Convention
786
+
787
+
All tool IDs referenced in `tools.access` and returned by `tools.config.tool` MUST use `snake_case` (e.g., `x_create_tweet`, `slack_send_message`). Never use camelCase or PascalCase.
788
+
698
789
## Checklist Before Finishing
699
790
700
791
-[ ] All subBlocks have `id`, `title` (except switch), and `type`
701
792
-[ ] Conditions use correct syntax (field, value, not, and)
702
793
-[ ] DependsOn set for fields that need other values
703
794
-[ ] Required fields marked correctly (boolean or condition)
704
795
-[ ] OAuth inputs have correct `serviceId`
705
-
-[ ] Tools.access lists all tool IDs
706
-
-[ ] Tools.config.tool returns correct tool ID
796
+
-[ ] Tools.access lists all tool IDs (snake_case)
797
+
-[ ] Tools.config.tool returns correct tool ID (snake_case)
- Set `optional: true` for outputs that may not exist
104
104
- 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
105
106
106
107
## Step 3: Create Block
107
108
@@ -436,6 +437,12 @@ If creating V2 versions (API-aligned outputs):
436
437
-[ ] Ran `bun run scripts/generate-docs.ts`
437
438
-[ ] Verified docs file created
438
439
440
+
### Final Validation (Required)
441
+
-[ ] Read every tool file and cross-referenced inputs/outputs against the API docs
442
+
-[ ] Verified block subBlocks cover all required tool params with correct conditions
443
+
-[ ] Verified block outputs match what the tools actually return
444
+
-[ ] Verified `tools.config.params` correctly maps and coerces all param types
445
+
439
446
## Example Command
440
447
441
448
When the user asks to add an integration:
@@ -685,13 +692,40 @@ return NextResponse.json({
685
692
|`isUserFile`|`@/lib/core/utils/user-file`| Type guard for UserFile objects |
686
693
|`FileInputSchema`|`@/lib/uploads/utils/file-schemas`| Zod schema for file validation |
687
694
695
+
### Advanced Mode for Optional Fields
696
+
697
+
Optional fields that are rarely used should be set to `mode: 'advanced'` so they don't clutter the basic UI. Examples: pagination tokens, time range filters, sort order, max results, reply settings.
698
+
699
+
### WandConfig for Complex Inputs
700
+
701
+
Use `wandConfig` for fields that are hard to fill out manually:
702
+
-**Timestamps**: Use `generationType: 'timestamp'` to inject current date context into the AI prompt
703
+
-**JSON arrays**: Use `generationType: 'json-object'` for structured data
704
+
-**Complex queries**: Use a descriptive prompt explaining the expected format
705
+
706
+
```typescript
707
+
{
708
+
id: 'startTime',
709
+
title: 'Start Time',
710
+
type: 'short-input',
711
+
mode: 'advanced',
712
+
wandConfig: {
713
+
enabled: true,
714
+
prompt: 'Generate an ISO 8601 timestamp. Return ONLY the timestamp string.',
715
+
generationType: 'timestamp',
716
+
},
717
+
}
718
+
```
719
+
688
720
### Common Gotchas
689
721
690
722
1.**OAuth serviceId must match** - The `serviceId` in oauth-input must match the OAuth provider configuration
691
-
2.**Tool IDs are snake_case** - `stripe_create_payment`, not `stripeCreatePayment`
723
+
2.**All tool IDs MUST be snake_case** - `stripe_create_payment`, not `stripeCreatePayment`. This applies to tool `id` fields, registry keys, `tools.access` arrays, and `tools.config.tool` return values
692
724
3.**Block type is snake_case** - `type: 'stripe'`, not `type: 'Stripe'`
693
725
4.**Alphabetical ordering** - Keep imports and registry entries alphabetically sorted
694
726
5.**Required can be conditional** - Use `required: { field: 'op', value: 'create' }` instead of always true
695
727
6.**DependsOn clears options** - When a dependency changes, selector options are refetched
696
728
7.**Never pass Buffer directly to fetch** - Convert to `new Uint8Array(buffer)` for TypeScript compatibility
Copy file name to clipboardExpand all lines: .claude/commands/add-tools.md
+40-3Lines changed: 40 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -147,9 +147,18 @@ closedAt: {
147
147
},
148
148
```
149
149
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
+
152
154
```typescript
155
+
// BAD: Opaque json with no info about what's inside
Only use bare `type: 'json'` without `properties` when the shape is truly dynamic or unknown.
189
+
176
190
## Critical Rules for transformResponse
177
191
178
192
### Handle Nullable Fields
@@ -272,13 +286,36 @@ If creating V2 tools (API-aligned outputs), use `_v2` suffix:
272
286
- Version: `'2.0.0'`
273
287
- Outputs: Flat, API-aligned (no content/metadata wrapper)
274
288
289
+
## Naming Convention
290
+
291
+
All tool IDs MUST use `snake_case`: `{service}_{action}` (e.g., `x_create_tweet`, `slack_send_message`). Never use camelCase or PascalCase for tool IDs.
292
+
275
293
## Checklist Before Finishing
276
294
295
+
-[ ] All tool IDs use snake_case
277
296
-[ ] All params have explicit `required: true` or `required: false`
278
297
-[ ] All params have appropriate `visibility`
279
298
-[ ] All nullable response fields use `?? null`
280
299
-[ ] All optional outputs have `optional: true`
281
300
-[ ] No raw JSON dumps in outputs
282
301
-[ ] Types file has all interfaces
283
302
-[ ] Index.ts exports all tools
284
-
-[ ] Tool IDs use snake_case
303
+
304
+
## Final Validation (Required)
305
+
306
+
After creating all tools, you MUST validate every tool before finishing:
307
+
308
+
1.**Read every tool file** you created — do not skip any
309
+
2.**Cross-reference with the API docs** to verify:
310
+
- All required params are marked `required: true`
311
+
- All optional params are marked `required: false`
312
+
- Param types match the API (string, number, boolean, json)
313
+
- Request URL, method, headers, and body match the API spec
314
+
-`transformResponse` extracts the correct fields from the API response
315
+
- All output fields match what the API actually returns
316
+
- No fields are missing from outputs that the API provides
317
+
- No extra fields are defined in outputs that the API doesn't return
318
+
3.**Verify consistency** across tools:
319
+
- Shared types in `types.ts` match all tools that use them
320
+
- Tool IDs in the barrel export match the tool file definitions
321
+
- Error handling is consistent (error checks, meaningful messages)
0 commit comments