Skip to content

Commit 316bc8c

Browse files
authored
v0.6.27: new triggers, mothership improvements, files archive, queueing improvements, posthog, secrets mutations
2 parents d889f32 + 68df732 commit 316bc8c

File tree

291 files changed

+35468
-7832
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

291 files changed

+35468
-7832
lines changed

.agents/skills/add-trigger/SKILL.md

Lines changed: 159 additions & 509 deletions
Large diffs are not rendered by default.
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
---
2+
name: validate-trigger
3+
description: Audit an existing Sim webhook trigger against the service's webhook API docs and repository conventions, then report and fix issues across trigger definitions, provider handler, output alignment, registration, and security. Use when validating or repairing a trigger under `apps/sim/triggers/{service}/` or `apps/sim/lib/webhooks/providers/{service}.ts`.
4+
---
5+
6+
# Validate Trigger
7+
8+
You are an expert auditor for Sim webhook triggers. Your job is to validate that an existing trigger implementation is correct, complete, secure, and aligned across all layers.
9+
10+
## Your Task
11+
12+
1. Read the service's webhook/API documentation (via WebFetch)
13+
2. Read every trigger file, provider handler, and registry entry
14+
3. Cross-reference against the API docs and Sim conventions
15+
4. Report all issues grouped by severity (critical, warning, suggestion)
16+
5. Fix all issues after reporting them
17+
18+
## Step 1: Gather All Files
19+
20+
Read **every** file for the trigger — do not skip any:
21+
22+
```
23+
apps/sim/triggers/{service}/ # All trigger files, utils.ts, index.ts
24+
apps/sim/lib/webhooks/providers/{service}.ts # Provider handler (if exists)
25+
apps/sim/lib/webhooks/providers/registry.ts # Handler registry
26+
apps/sim/triggers/registry.ts # Trigger registry
27+
apps/sim/blocks/blocks/{service}.ts # Block definition (trigger wiring)
28+
```
29+
30+
Also read for reference:
31+
```
32+
apps/sim/lib/webhooks/providers/types.ts # WebhookProviderHandler interface
33+
apps/sim/lib/webhooks/providers/utils.ts # Shared helpers (createHmacVerifier, etc.)
34+
apps/sim/lib/webhooks/provider-subscription-utils.ts # Subscription helpers
35+
apps/sim/lib/webhooks/processor.ts # Central webhook processor
36+
```
37+
38+
## Step 2: Pull API Documentation
39+
40+
Fetch the service's official webhook documentation. This is the **source of truth** for:
41+
- Webhook event types and payload shapes
42+
- Signature/auth verification method (HMAC algorithm, header names, secret format)
43+
- Challenge/verification handshake requirements
44+
- Webhook subscription API (create/delete endpoints, if applicable)
45+
- Retry behavior and delivery guarantees
46+
47+
## Step 3: Validate Trigger Definitions
48+
49+
### utils.ts
50+
- [ ] `{service}TriggerOptions` lists all trigger IDs accurately
51+
- [ ] `{service}SetupInstructions` provides clear, correct steps for the service
52+
- [ ] `build{Service}ExtraFields` includes relevant filter/config fields with correct `condition`
53+
- [ ] Output builders expose all meaningful fields from the webhook payload
54+
- [ ] Output builders do NOT use `optional: true` or `items` (tool-output-only features)
55+
- [ ] Nested output objects correctly model the payload structure
56+
57+
### Trigger Files
58+
- [ ] Exactly one primary trigger has `includeDropdown: true`
59+
- [ ] All secondary triggers do NOT have `includeDropdown`
60+
- [ ] All triggers use `buildTriggerSubBlocks` helper (not hand-rolled subBlocks)
61+
- [ ] Every trigger's `id` matches the convention `{service}_{event_name}`
62+
- [ ] Every trigger's `provider` matches the service name used in the handler registry
63+
- [ ] `index.ts` barrel exports all triggers
64+
65+
### Trigger ↔ Provider Alignment (CRITICAL)
66+
- [ ] Every trigger ID referenced in `matchEvent` logic exists in `{service}TriggerOptions`
67+
- [ ] Event matching logic in the provider correctly maps trigger IDs to service event types
68+
- [ ] Event matching logic in `is{Service}EventMatch` (if exists) correctly identifies events per the API docs
69+
70+
## Step 4: Validate Provider Handler
71+
72+
### Auth Verification
73+
- [ ] `verifyAuth` correctly validates webhook signatures per the service's documentation
74+
- [ ] HMAC algorithm matches (SHA-1, SHA-256, SHA-512)
75+
- [ ] Signature header name matches the API docs exactly
76+
- [ ] Signature format is handled (raw hex, `sha256=` prefix, base64, etc.)
77+
- [ ] Uses `safeCompare` for timing-safe comparison (no `===`)
78+
- [ ] If `webhookSecret` is required, handler rejects when it's missing (fail-closed)
79+
- [ ] Signature is computed over raw body (not parsed JSON)
80+
81+
### Event Matching
82+
- [ ] `matchEvent` returns `boolean` (not `NextResponse` or other values)
83+
- [ ] Challenge/verification events are excluded from matching (e.g., `endpoint.url_validation`)
84+
- [ ] When `triggerId` is a generic webhook ID, all events pass through
85+
- [ ] When `triggerId` is specific, only matching events pass
86+
- [ ] Event matching logic uses dynamic `await import()` for trigger utils (avoids circular deps)
87+
88+
### formatInput (CRITICAL)
89+
- [ ] Every key in the `formatInput` return matches a key in the trigger `outputs` schema
90+
- [ ] Every key in the trigger `outputs` schema is populated by `formatInput`
91+
- [ ] No extra undeclared keys that users can't discover in the UI
92+
- [ ] No wrapper objects (`webhook: { ... }`, `{service}: { ... }`)
93+
- [ ] Nested output paths exist at the correct depth (e.g., `resource.id` actually has `resource: { id: ... }`)
94+
- [ ] `null` is used for missing optional fields (not empty strings or empty objects)
95+
- [ ] Returns `{ input: { ... } }` — not a bare object
96+
97+
### Idempotency
98+
- [ ] `extractIdempotencyId` returns a stable, unique key per delivery
99+
- [ ] Uses provider-specific delivery IDs when available (e.g., `X-Request-Id`, `Linear-Delivery`, `svix-id`)
100+
- [ ] Falls back to content-based ID (e.g., `${type}:${id}`) when no delivery header exists
101+
- [ ] Does NOT include timestamps in the idempotency key (would break dedup on retries)
102+
103+
### Challenge Handling (if applicable)
104+
- [ ] `handleChallenge` correctly implements the service's URL verification handshake
105+
- [ ] Returns the expected response format per the API docs
106+
- [ ] Env-backed secrets are resolved via `resolveEnvVarsInObject` if needed
107+
108+
## Step 5: Validate Automatic Subscription Lifecycle
109+
110+
If the service supports programmatic webhook creation:
111+
112+
### createSubscription
113+
- [ ] Calls the correct API endpoint to create a webhook
114+
- [ ] Sends the correct event types/filters
115+
- [ ] Passes the notification URL from `getNotificationUrl(ctx.webhook)`
116+
- [ ] Returns `{ providerConfigUpdates: { externalId } }` with the external webhook ID
117+
- [ ] Throws on failure (orchestration handles rollback)
118+
- [ ] Provides user-friendly error messages (401 → "Invalid API Key", etc.)
119+
120+
### deleteSubscription
121+
- [ ] Calls the correct API endpoint to delete the webhook
122+
- [ ] Handles 404 gracefully (webhook already deleted)
123+
- [ ] Never throws — catches errors and logs non-fatally
124+
- [ ] Skips gracefully when `apiKey` or `externalId` is missing
125+
126+
### Orchestration Isolation
127+
- [ ] NO provider-specific logic in `route.ts`, `provider-subscriptions.ts`, or `deploy.ts`
128+
- [ ] All subscription logic lives on the handler (`createSubscription`/`deleteSubscription`)
129+
130+
## Step 6: Validate Registration and Block Wiring
131+
132+
### Trigger Registry (`triggers/registry.ts`)
133+
- [ ] All triggers are imported and registered
134+
- [ ] Registry keys match trigger IDs exactly
135+
- [ ] No orphaned entries (triggers that don't exist)
136+
137+
### Provider Handler Registry (`providers/registry.ts`)
138+
- [ ] Handler is imported and registered (if handler exists)
139+
- [ ] Registry key matches the `provider` field on the trigger configs
140+
- [ ] Entries are in alphabetical order
141+
142+
### Block Wiring (`blocks/blocks/{service}.ts`)
143+
- [ ] Block has `triggers.enabled: true`
144+
- [ ] `triggers.available` lists all trigger IDs
145+
- [ ] All trigger subBlocks are spread into `subBlocks`: `...getTrigger('id').subBlocks`
146+
- [ ] No trigger IDs in `triggers.available` that aren't in the registry
147+
- [ ] No trigger subBlocks spread that aren't in `triggers.available`
148+
149+
## Step 7: Validate Security
150+
151+
- [ ] Webhook secrets are never logged (not even at debug level)
152+
- [ ] Auth verification runs before any event processing
153+
- [ ] No secret comparison uses `===` (must use `safeCompare` or `crypto.timingSafeEqual`)
154+
- [ ] Timestamp/replay protection is reasonable (not too tight for retries, not too loose for security)
155+
- [ ] Raw body is used for signature verification (not re-serialized JSON)
156+
157+
## Step 8: Report and Fix
158+
159+
### Report Format
160+
161+
Group findings by severity:
162+
163+
**Critical** (runtime errors, security issues, or data loss):
164+
- Wrong HMAC algorithm or header name
165+
- `formatInput` keys don't match trigger `outputs`
166+
- Missing `verifyAuth` when the service sends signed webhooks
167+
- `matchEvent` returns non-boolean values
168+
- Provider-specific logic leaking into shared orchestration files
169+
- Trigger IDs mismatch between trigger files, registry, and block
170+
- `createSubscription` calling wrong API endpoint
171+
- Auth comparison using `===` instead of `safeCompare`
172+
173+
**Warning** (convention violations or usability issues):
174+
- Missing `extractIdempotencyId` when the service provides delivery IDs
175+
- Timestamps in idempotency keys (breaks dedup on retries)
176+
- Missing challenge handling when the service requires URL verification
177+
- Output schema missing fields that `formatInput` returns (undiscoverable data)
178+
- Overly tight timestamp skew window that rejects legitimate retries
179+
- `matchEvent` not filtering challenge/verification events
180+
- Setup instructions missing important steps
181+
182+
**Suggestion** (minor improvements):
183+
- More specific output field descriptions
184+
- Additional output fields that could be exposed
185+
- Better error messages in `createSubscription`
186+
- Logging improvements
187+
188+
### Fix All Issues
189+
190+
After reporting, fix every **critical** and **warning** issue. Apply **suggestions** where they don't add unnecessary complexity.
191+
192+
### Validation Output
193+
194+
After fixing, confirm:
195+
1. `bun run type-check` passes
196+
2. Re-read all modified files to verify fixes are correct
197+
3. Provider handler tests pass (if they exist): `bun test {service}`
198+
199+
## Checklist Summary
200+
201+
- [ ] Read all trigger files, provider handler, types, registries, and block
202+
- [ ] Pulled and read official webhook/API documentation
203+
- [ ] Validated trigger definitions: options, instructions, extra fields, outputs
204+
- [ ] Validated primary/secondary trigger distinction (`includeDropdown`)
205+
- [ ] Validated provider handler: auth, matchEvent, formatInput, idempotency
206+
- [ ] Validated output alignment: every `outputs` key ↔ every `formatInput` key
207+
- [ ] Validated subscription lifecycle: createSubscription, deleteSubscription, no shared-file edits
208+
- [ ] Validated registration: trigger registry, handler registry, block wiring
209+
- [ ] Validated security: safe comparison, no secret logging, replay protection
210+
- [ ] Reported all issues grouped by severity
211+
- [ ] Fixed all critical and warning issues
212+
- [ ] `bun run type-check` passes after fixes

0 commit comments

Comments
 (0)