vybekiit 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/bin.js +6457 -6312
  2. package/dist/global-skills/aws-serverless/SKILL.md +44 -44
  3. package/dist/global-skills/aws-serverless/assets/powertools-handler.py +2 -1
  4. package/dist/global-skills/aws-serverless/references/api-gateway.md +50 -470
  5. package/dist/global-skills/aws-serverless/references/architecture.md +47 -186
  6. package/dist/global-skills/aws-serverless/references/concurrency.md +44 -158
  7. package/dist/global-skills/aws-serverless/references/deployment.md +1 -1
  8. package/dist/global-skills/aws-serverless/references/event-sources.md +72 -391
  9. package/dist/global-skills/aws-serverless/references/lambda.md +69 -428
  10. package/dist/global-skills/aws-serverless/references/orchestration.md +65 -384
  11. package/dist/global-skills/aws-serverless/references/production.md +78 -415
  12. package/dist/global-skills/aws-serverless/references/troubleshooting.md +79 -626
  13. package/dist/global-skills/email-best-practices/.github/workflows/sync-skills.yml +30 -0
  14. package/dist/global-skills/email-best-practices/README.md +63 -0
  15. package/dist/global-skills/email-best-practices/references/accessibility.md +189 -0
  16. package/dist/global-skills/email-best-practices/references/compliance.md +125 -0
  17. package/dist/global-skills/email-best-practices/references/deliverability.md +121 -0
  18. package/dist/global-skills/email-best-practices/references/email-capture.md +129 -0
  19. package/dist/global-skills/email-best-practices/references/email-types.md +173 -0
  20. package/dist/global-skills/email-best-practices/references/list-management.md +157 -0
  21. package/dist/global-skills/email-best-practices/references/marketing-emails.md +115 -0
  22. package/dist/global-skills/email-best-practices/references/sending-reliability.md +155 -0
  23. package/dist/global-skills/email-best-practices/references/transactional-email-catalog.md +418 -0
  24. package/dist/global-skills/email-best-practices/references/transactional-emails.md +92 -0
  25. package/dist/global-skills/email-best-practices/references/webhooks-events.md +167 -0
  26. package/dist/global-skills/email-best-practices/tests/README.md +35 -0
  27. package/dist/global-skills/email-best-practices/tests/scenarios/01-spam-deliverability.md +46 -0
  28. package/dist/global-skills/email-best-practices/tests/scenarios/02-multi-region-compliance.md +48 -0
  29. package/dist/global-skills/email-best-practices/tests/scenarios/03-retry-idempotency.md +36 -0
  30. package/dist/global-skills/email-best-practices/tests/scenarios/04-webhook-bounce-handling.md +52 -0
  31. package/dist/global-skills/email-best-practices/tests/scenarios/05-new-saas-email-plan.md +51 -0
  32. package/dist/global-skills/instrument-feature-flags/references/usage.md +35 -0
  33. package/dist/global-skills/instrument-product-analytics/SKILL.md +1 -1
  34. package/dist/global-skills/instrument-product-analytics/references/android.md +36 -0
  35. package/dist/global-skills/instrument-product-analytics/references/configuration.md +1 -0
  36. package/dist/global-skills/instrument-product-analytics/references/flutter.md +37 -0
  37. package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +3 -2
  38. package/dist/global-skills/instrument-product-analytics/references/usage.md +35 -0
  39. package/dist/global-skills/neon/SKILL.md +27 -20
  40. package/dist/global-skills/neon-ai-gateway/SKILL.md +68 -2
  41. package/dist/global-skills/neon-functions/SKILL.md +7 -7
  42. package/dist/global-skills/neon-object-storage/SKILL.md +2 -2
  43. package/dist/global-skills/neon-postgres/SKILL.md +5 -5
  44. package/dist/global-skills/neon-postgres/references/neon-sdk.md +262 -0
  45. package/dist/global-skills/neon-postgres-branches/SKILL.md +1 -1
  46. package/dist/global-skills/stripe-best-practices/SKILL.md +11 -6
  47. package/dist/global-skills/stripe-best-practices/references/billing.md +5 -0
  48. package/dist/global-skills/stripe-best-practices/references/payments.md +4 -2
  49. package/dist/global-skills/stripe-best-practices/references/tax.md +78 -8
  50. package/package.json +7 -7
@@ -0,0 +1,46 @@
1
+ # Scenario 1: Emails Going to Spam
2
+
3
+ ## Prompt
4
+
5
+ ```
6
+ You are an AI coding assistant. A developer asks you:
7
+
8
+ "My transactional emails (password resets, order confirmations) are going to spam in Gmail. What do I do to fix this?"
9
+
10
+ Answer with specific, actionable steps. Include exact DNS records, commands to verify, and threshold numbers where relevant.
11
+
12
+ Format your response as a numbered action plan.
13
+ ```
14
+
15
+ ## Expected Correctness Criteria
16
+
17
+ The agent MUST include these skill-specific details:
18
+
19
+ ### Authentication (deliverability.md)
20
+ - [ ] SPF record example: `v=spf1 include:amazonses.com ~all`
21
+ - [ ] DKIM: provider supplies the record
22
+ - [ ] DMARC: `v=DMARC1; p=none; rua=mailto:dmarc@example.com`
23
+ - [ ] DMARC rollout: `p=none` → `p=quarantine; pct=25` → `p=reject`
24
+ - [ ] Verification commands: `dig TXT example.com +short`, `dig TXT resend._domainkey.example.com +short`, `dig TXT _dmarc.example.com +short`
25
+
26
+ ### Thresholds (deliverability.md)
27
+ - [ ] Bounce targets: <1% good, 1-3% acceptable, 3-4% concerning, >4% critical
28
+ - [ ] Complaint targets: <0.01% excellent, 0.01-0.05% good, >0.05% critical
29
+
30
+ ### IP Warming (deliverability.md)
31
+ - [ ] Week 1: 50-100/day
32
+ - [ ] Week 2: 200-500/day
33
+ - [ ] Week 3: 1,000-2,000/day
34
+ - [ ] Week 4: 5,000-10,000/day
35
+
36
+ ### Infrastructure (deliverability.md)
37
+ - [ ] Dedicated subdomains: `t.example.com` (transactional), `m.example.com` (marketing)
38
+ - [ ] DNS TTL: 300s during setup, 3600s+ after stable
39
+
40
+ ### Troubleshooting order (deliverability.md)
41
+ - [ ] Check in order: 1. Authentication, 2. List-Unsubscribe header, 3. Reputation, 4. Content, 5. Sending patterns
42
+
43
+ ### Diagnostic tools (deliverability.md)
44
+ - [ ] Google Postmaster Tools
45
+ - [ ] mail-tester.com
46
+ - [ ] MXToolbox blacklist check
@@ -0,0 +1,48 @@
1
+ # Scenario 2: Multi-Region Email Compliance
2
+
3
+ ## Prompt
4
+
5
+ ```
6
+ You are an AI coding assistant. A developer asks you:
7
+
8
+ "I'm building an email newsletter for my SaaS product. I have users in the US, EU, and Canada. What legal requirements do I need to follow? Give me a comparison table of requirements by region and the specific implementation steps."
9
+
10
+ Be specific about penalty amounts, timing requirements for unsubscribe processing, and consent record requirements.
11
+ ```
12
+
13
+ ## Expected Correctness Criteria
14
+
15
+ ### Penalties (compliance.md)
16
+ - [ ] CAN-SPAM: $53k/email
17
+ - [ ] GDPR: EUR 20M or 4% revenue
18
+ - [ ] CASL: $1M (individual) to $10M (organization) CAD
19
+
20
+ ### Consent types (compliance.md)
21
+ - [ ] CAN-SPAM: opt-out model (can send without opt-in)
22
+ - [ ] GDPR: explicit opt-in (no pre-checked boxes)
23
+ - [ ] CASL express: explicit opt-in
24
+ - [ ] CASL implied: existing relationship (2 years) or inquiry (6 months)
25
+
26
+ ### Unsubscribe timing (compliance.md)
27
+ - [ ] CAN-SPAM: 10 business days, must work 30 days after send
28
+ - [ ] GDPR: immediately, as easy as opting in
29
+ - [ ] CASL: 10 business days, must work 60 days after send
30
+
31
+ ### CASL specifics (compliance.md)
32
+ - [ ] Sender identification valid 60 days after send
33
+ - [ ] Keep consent records 3 years after expiration
34
+
35
+ ### Consent records (compliance.md)
36
+ - [ ] Record: email, date/time, method, what consented to, source
37
+
38
+ ### International sending (compliance.md)
39
+ - [ ] Best practice: follow GDPR (most restrictive) for all regions
40
+
41
+ ### Managing preferences vs unsubscribe (compliance.md)
42
+ - [ ] One-click unsubscribe required; preference management is nice-to-have, doesn't replace unsubscribe
43
+
44
+ ### List-Unsubscribe header (compliance.md)
45
+ - [ ] Required by Gmail/Yahoo since Feb 2024
46
+ - [ ] Headers: `List-Unsubscribe` URL + `List-Unsubscribe-Post: List-Unsubscribe=One-Click`
47
+ - [ ] Endpoint: POST returns 200/202, GET shows unsubscribe page
48
+ - [ ] Stop sending within 48 hours
@@ -0,0 +1,36 @@
1
+ # Scenario 3: Retry Logic + Idempotency
2
+
3
+ ## Prompt
4
+
5
+ ```
6
+ You are an AI coding assistant. A developer asks you:
7
+
8
+ "I'm using the Resend API to send transactional emails. I need to implement retry logic with idempotency to prevent duplicate sends. Show me a TypeScript implementation with idempotency keys, exponential backoff, and proper error code handling."
9
+
10
+ Include specific HTTP error codes and which ones to retry vs not retry, idempotency key generation strategies, and backoff timing.
11
+ ```
12
+
13
+ ## Expected Correctness Criteria
14
+
15
+ ### Idempotency keys (sending-reliability.md)
16
+ - [ ] Event-based key example: `order-confirm-${orderId}` (recommended)
17
+ - [ ] Request-scoped example: `reset-${userId}-${resetRequestId}`
18
+ - [ ] UUID fallback: `crypto.randomUUID()` — generate once, reuse on retry
19
+ - [ ] Warns against `Date.now()` or random values generated fresh on each attempt
20
+ - [ ] Key expiration: 24 hours — complete retry logic within this window
21
+
22
+ ### Error codes (sending-reliability.md)
23
+ - [ ] Retry: 5xx (server error), 429 (rate limit), network timeout, DNS failure
24
+ - [ ] Do NOT retry: 400 (bad request), 401 (unauthorized), 403 (forbidden), 404 (not found), 422 (validation)
25
+
26
+ ### Backoff (sending-reliability.md)
27
+ - [ ] Exponential: 1s -> 2s -> 4s -> 8s
28
+ - [ ] Cap at 30 seconds
29
+ - [ ] Jitter to prevent thundering herd
30
+ - [ ] Max retries: 3
31
+
32
+ ### Timeout (sending-reliability.md)
33
+ - [ ] AbortController pattern with 10-30 second timeout
34
+
35
+ ### Queuing (sending-reliability.md)
36
+ - [ ] Queue pattern for critical emails: write pending -> attempt send -> mark sent/schedule retry -> mark failed + alert
@@ -0,0 +1,52 @@
1
+ # Scenario 4: Webhook Bounce/Complaint Handling
2
+
3
+ ## Prompt
4
+
5
+ ```
6
+ You are an AI coding assistant. A developer asks you:
7
+
8
+ "I need to set up Resend webhooks to handle bounces and complaints. Show me how to implement this with signature verification using svix, idempotent event processing, and proper bounce/complaint handling (when to suppress, when to retry). Include TypeScript code."
9
+
10
+ Be specific about: svix verification headers, hard vs soft bounce handling thresholds, and complaint handling requirements.
11
+ ```
12
+
13
+ ## Expected Correctness Criteria
14
+
15
+ ### Webhook setup (webhooks-events.md)
16
+ - [ ] Endpoint must return 2xx within 5 seconds
17
+ - [ ] Return 200 immediately, process asynchronously
18
+
19
+ ### Svix verification (webhooks-events.md)
20
+ - [ ] Import from 'svix'
21
+ - [ ] Headers: `svix-id`, `svix-timestamp`, `svix-signature`
22
+ - [ ] Verify before processing, return 400 on invalid signature
23
+
24
+ ### Idempotent processing (webhooks-events.md)
25
+ - [ ] Use event ID to deduplicate
26
+ - [ ] Check if already processed before handling
27
+ - [ ] Mark as processed after handling
28
+
29
+ ### Event types (webhooks-events.md)
30
+ - [ ] `email.sent`, `email.delivered`, `email.bounced`, `email.complained`, `email.opened`, `email.clicked`
31
+
32
+ ### Bounce handling (webhooks-events.md + list-management.md)
33
+ - [ ] Hard bounce: suppress immediately, remove from all lists
34
+ - [ ] Soft bounce: track count, suppress after 3 failures
35
+ - [ ] Suppression entry schema includes: email, reason, created_at, source_email_id
36
+
37
+ ### Complaint handling (webhooks-events.md + list-management.md)
38
+ - [ ] Immediate suppression — no exceptions
39
+ - [ ] Remove from all lists
40
+ - [ ] Log for analysis
41
+
42
+ ### Suppression unsuppress rules (list-management.md)
43
+ - [ ] Hard bounce: cannot unsuppress (address invalid)
44
+ - [ ] Complaint: cannot unsuppress (legal requirement)
45
+ - [ ] Soft bounce (3x): can unsuppress after 30-90 days
46
+ - [ ] Manual removal: only if user requests
47
+
48
+ ### Pre-send check (list-management.md)
49
+ - [ ] Always check suppression before sending
50
+
51
+ ### Retry behavior (webhooks-events.md)
52
+ - [ ] Non-2xx triggers retries: ~30s -> ~1min -> ~5min (continues ~24 hours)
@@ -0,0 +1,51 @@
1
+ # Scenario 5: New SaaS Email Infrastructure Plan
2
+
3
+ ## Prompt
4
+
5
+ ```
6
+ You are an AI coding assistant. A developer asks you:
7
+
8
+ "I'm building a new SaaS app and need to plan my entire email infrastructure. I need to know: (1) what types of transactional emails I should plan for, (2) how to set up DNS authentication, (3) how to warm up my sending domain, (4) how to handle bounces/complaints in production, and (5) what compliance requirements I need for international users. Give me a comprehensive implementation roadmap."
9
+
10
+ Be specific about: IP warming schedules (daily volumes by week), bounce rate thresholds, complaint rate thresholds, DNS record formats, and legal requirements by region.
11
+ ```
12
+
13
+ ## Expected Correctness Criteria
14
+
15
+ ### Email planning (transactional-email-catalog.md)
16
+ - [ ] References the transactional email catalog for SaaS planning
17
+ - [ ] Covers at minimum: verification, password reset, OTP/2FA, security alerts, billing
18
+
19
+ ### DNS authentication (deliverability.md)
20
+ - [ ] SPF, DKIM, DMARC records with examples
21
+ - [ ] DMARC rollout strategy (none -> quarantine; pct=25 -> reject)
22
+ - [ ] Dedicated subdomains for transactional vs marketing
23
+
24
+ ### Warming (deliverability.md)
25
+ - [ ] Correct weekly schedule: 50-100 / 200-500 / 1k-2k / 5k-10k
26
+ - [ ] Start with engaged users, send consistently
27
+
28
+ ### Bounce/complaint handling (deliverability.md + list-management.md + webhooks-events.md)
29
+ - [ ] Bounce thresholds: <1% good, >4% critical
30
+ - [ ] Complaint thresholds: <0.01% excellent, >0.05% critical
31
+ - [ ] Hard bounce: immediate suppression
32
+ - [ ] Soft bounce: suppress after 3 failures
33
+ - [ ] Complaint: immediate suppression
34
+ - [ ] Pre-send suppression check
35
+
36
+ ### Compliance (compliance.md)
37
+ - [ ] Covers CAN-SPAM, GDPR, CASL
38
+ - [ ] Correct penalty amounts
39
+ - [ ] Correct unsubscribe timing by region
40
+ - [ ] Recommends GDPR as global standard
41
+
42
+ ### Data retention (list-management.md)
43
+ - [ ] Send attempts: 90 days
44
+ - [ ] Bounce/complaint events: 3 years
45
+ - [ ] Suppression list: indefinite
46
+ - [ ] Email content: 30 days
47
+ - [ ] Consent records: 3 years after expiry
48
+
49
+ ### Cross-resource synthesis
50
+ - [ ] Agent references multiple resource files (not just one)
51
+ - [ ] "Start Here" routing from SKILL.md is followed
@@ -534,6 +534,41 @@ PostHogSDK.shared.captureFeatureView(flag: "flag-key", flagVariant: "variant-key
534
534
  PostHogSDK.shared.captureFeatureInteraction(flag: "flag-key", flagVariant: "variant-key")
535
535
  ```
536
536
 
537
+ ### Bootstrapping flags
538
+
539
+ Since there is a delay between initializing PostHog and fetching feature flags, feature flags are not always available immediately. This makes them unusable if you want to do something like redirecting a user to a different page based on a feature flag.
540
+
541
+ To have your feature flags available immediately, you can initialize PostHog with precomputed values until it has had a chance to fetch them. This is called bootstrapping. After the SDK fetches feature flags from PostHog, it will use those flag values instead of bootstrapped ones.
542
+
543
+ Set `config.bootstrap` before calling `setup()` to seed identity and flag values before the first `/flags` response (requires iOS SDK `3.66.0`+):
544
+
545
+ Swift
546
+
547
+ PostHog AI
548
+
549
+ ```swift
550
+ let config = PostHogConfig(projectToken: "<ph_project_token>", host: "https://us.i.posthog.com")
551
+ config.bootstrap = PostHogBootstrapConfig(
552
+ distinctId: "distinct_id_of_your_user",
553
+ isIdentifiedId: true,
554
+ featureFlags: [
555
+ "flag-1": true,
556
+ "variant-flag": "control"
557
+ ],
558
+ featureFlagPayloads: nil
559
+ )
560
+ PostHogSDK.shared.setup(config)
561
+ ```
562
+
563
+ - **Bootstrapped identity applies to the first session.** Setting it before `setup()` means events captured synchronously during initialization (like `Application Installed`) carry your distinct ID instead of the SDK-generated UUID.
564
+ - An **anonymous** bootstrap (`isIdentifiedId: false`, the default) seeds the anonymous ID only when none is persisted yet. Once an anonymous ID exists on disk, or the user has been identified, it is ignored.
565
+ - An **identified** bootstrap (`isIdentifiedId: true`) is for a user you've already identified outside the SDK (for example, from a backend session token). On a fresh install it seeds the distinct ID and marks the user identified. On a returning install where an anonymous user already exists, it merges that user into the identified ID via `identify()`, which emits a `$identify` event during `setup()`. A *different*, already-identified user is left untouched. The identified ID never becomes the device ID.
566
+ - **Bootstrapped flags are served until the first `/flags` response, then replaced.** A complete `/flags` response takes over entirely, so bootstrapped-only keys don't persist past it. Only *enabled* flags are seeded: a `true` boolean or a non-empty variant string. A `false` or empty value is dropped, matching posthog-js. Seed payloads with the separate `featureFlagPayloads` option. Flag values and payloads must be JSON-serializable, or they're dropped. Bootstrapped flags are cleared on `reset()`.
567
+
568
+ The feature-flags-loaded signal fires as soon as bootstrapped flags are applied, so startup logic can read them immediately. These SDKs don't support the `sessionID` bootstrap option.
569
+
570
+ See the [bootstrapping guide](/docs/feature-flags/bootstrapping.md) for the cross-SDK overview.
571
+
537
572
  ## Experiments (A/B tests)
538
573
 
539
574
  Since [experiments](/docs/experiments/start-here.md) use feature flags, the code for running an experiment is very similar to the feature flags code. See [adding experiment code](/docs/experiments/adding-experiment-code.md) for iOS examples.
@@ -65,7 +65,7 @@ STEP 9: Set up environment variables.
65
65
  STEP 10: Verify and clean up.
66
66
  - Check the project for errors. Look for type checking or build scripts in package.json.
67
67
  - Ensure any components created were actually used.
68
- - Run any linter or prettier-like scripts found in the package.json.
68
+ - Run any linter or prettier-like scripts found in the package.json, but ONLY on the files you have edited or created during this session. Never run formatting or linting across the entire project's codebase.
69
69
 
70
70
  ## Reference files
71
71
 
@@ -566,6 +566,41 @@ PostHog.captureFeatureView("flag-key", flagVariant = "variant-key")
566
566
  PostHog.captureFeatureInteraction("flag-key", flagVariant = "variant-key")
567
567
  ```
568
568
 
569
+ ### Bootstrapping flags
570
+
571
+ Since there is a delay between initializing PostHog and fetching feature flags, feature flags are not always available immediately. This makes them unusable if you want to do something like redirecting a user to a different page based on a feature flag.
572
+
573
+ To have your feature flags available immediately, you can initialize PostHog with precomputed values until it has had a chance to fetch them. This is called bootstrapping. After the SDK fetches feature flags from PostHog, it will use those flag values instead of bootstrapped ones.
574
+
575
+ Set `config.bootstrap` before calling `setup()` to seed identity and flag values before the first `/flags` response (requires Android SDK `3.55.0`+):
576
+
577
+ Kotlin
578
+
579
+ PostHog AI
580
+
581
+ ```kotlin
582
+ import com.posthog.PostHogBootstrapConfig
583
+ val config = PostHogAndroidConfig(apiKey = POSTHOG_API_KEY, host = POSTHOG_HOST)
584
+ config.bootstrap = PostHogBootstrapConfig(
585
+ distinctId = "distinct_id_of_your_user",
586
+ isIdentifiedId = true,
587
+ featureFlags = mapOf(
588
+ "flag-1" to true,
589
+ "variant-flag" to "control"
590
+ )
591
+ )
592
+ PostHogAndroid.setup(this, config)
593
+ ```
594
+
595
+ - **Bootstrapped identity applies to the first session.** Setting it before `setup()` means events captured synchronously during initialization (like `Application Installed`) carry your distinct ID instead of the SDK-generated UUID.
596
+ - An **anonymous** bootstrap (`isIdentifiedId: false`, the default) seeds the anonymous ID only when none is persisted yet. Once an anonymous ID exists on disk, or the user has been identified, it is ignored.
597
+ - An **identified** bootstrap (`isIdentifiedId: true`) is for a user you've already identified outside the SDK (for example, from a backend session token). On a fresh install it seeds the distinct ID and marks the user identified. On a returning install where an anonymous user already exists, it merges that user into the identified ID via `identify()`, which emits a `$identify` event during `setup()`. A *different*, already-identified user is left untouched. The identified ID never becomes the device ID.
598
+ - **Bootstrapped flags are served until the first `/flags` response, then replaced.** A complete `/flags` response takes over entirely, so bootstrapped-only keys don't persist past it. Only *enabled* flags are seeded: a `true` boolean or a non-empty variant string. A `false` or empty value is dropped, matching posthog-js. Seed payloads with the separate `featureFlagPayloads` option. Flag values and payloads must be JSON-serializable, or they're dropped. Bootstrapped flags are cleared on `reset()`.
599
+
600
+ The feature-flags-loaded signal fires as soon as bootstrapped flags are applied, so startup logic can read them immediately. These SDKs don't support the `sessionID` bootstrap option.
601
+
602
+ See the [bootstrapping guide](/docs/feature-flags/bootstrapping.md) for the cross-SDK overview.
603
+
569
604
  ## Experiments (A/B tests)
570
605
 
571
606
  Since [experiments](/docs/experiments/start-here.md) use feature flags, the code for running an experiment is very similar to the feature flags code:
@@ -750,6 +785,7 @@ val config = PostHogAndroidConfig(
750
785
  | errorTrackingConfig | PostHogErrorTrackingConfig() | Configures error tracking. autoCapture defaults to false; set it to true to autocapture uncaught exceptions when project settings also enable error tracking. |
751
786
  | surveys | false | Internal/experimental native Android survey support. Native Android survey UI is not fully supported or documented yet. |
752
787
  | surveysConfig | PostHogSurveysConfig() | Internal/experimental survey display delegate configuration, primarily for hybrid SDKs. |
788
+ | bootstrap | null | Seeds identity (distinctId, isIdentifiedId) and feature-flag state (featureFlags, featureFlagPayloads) before the first /flags response. Bootstrapped identity applies to the first session; only enabled flags are served, until the first /flags response replaces them. See [bootstrapping](/docs/feature-flags/bootstrapping.md#behavior-on-mobile-sdks). |
753
789
 
754
790
  ### Event filtering with `beforeSend`
755
791
 
@@ -289,6 +289,7 @@ The [`PostHogConfig` object](https://github.com/PostHog/posthog-ios/blob/main/Po
289
289
  | reuseAnonymousIdType: BooleanDefault: false | Whether the SDK should reuse the anonymous Id between user changes. When enabled, a single Id will be used for all anonymous users on this device. |
290
290
  | surveysType: BooleanDefault: true | Enable Surveys. |
291
291
  | setBeforeSendType: FunctionDefault: undefined | Hook that allows for amending, sampling, or dropping events before they are sent to PostHog. |
292
+ | bootstrapType: PostHogBootstrapConfigDefault: nil | Seeds identity (distinctId, isIdentifiedId) and feature-flag state (featureFlags, featureFlagPayloads) before the first /flags response. Bootstrapped identity applies to the first session; only enabled flags are served, until the first /flags response replaces them. See [bootstrapping](/docs/feature-flags/bootstrapping.md#behavior-on-mobile-sdks). |
292
293
 
293
294
  ### Community questions
294
295
 
@@ -605,6 +605,43 @@ PostHog AI
605
605
  await Posthog().reloadFeatureFlags();
606
606
  ```
607
607
 
608
+ ### Bootstrapping flags
609
+
610
+ Since there is a delay between initializing PostHog and fetching feature flags, feature flags are not always available immediately. This makes them unusable if you want to do something like redirecting a user to a different page based on a feature flag.
611
+
612
+ To have your feature flags available immediately, you can initialize PostHog with precomputed values until it has had a chance to fetch them. This is called bootstrapping. After the SDK fetches feature flags from PostHog, it will use those flag values instead of bootstrapped ones.
613
+
614
+ Set `config.bootstrap` before calling `setup()` to seed identity and flag values before the first `/flags` response (requires the Flutter SDK `5.31.0`+):
615
+
616
+ Dart
617
+
618
+ PostHog AI
619
+
620
+ ```dart
621
+ final config = PostHogConfig('<ph_project_token>');
622
+ config.host = 'https://us.i.posthog.com';
623
+ config.bootstrap = PostHogBootstrapConfig(
624
+ distinctId: 'distinct_id_of_your_user',
625
+ isIdentifiedId: true,
626
+ featureFlags: {
627
+ 'flag-1': true,
628
+ 'variant-flag': 'control',
629
+ },
630
+ );
631
+ await Posthog().setup(config);
632
+ ```
633
+
634
+ The values are forwarded to the native iOS and Android SDKs:
635
+
636
+ - **Bootstrapped identity applies to the first session.** Setting it before `setup()` means events captured synchronously during initialization (like `Application Installed`) carry your distinct ID instead of the SDK-generated UUID.
637
+ - An **anonymous** bootstrap (`isIdentifiedId: false`, the default) seeds the anonymous ID only when none is persisted yet. Once an anonymous ID exists on disk, or the user has been identified, it is ignored.
638
+ - An **identified** bootstrap (`isIdentifiedId: true`) is for a user you've already identified outside the SDK (for example, from a backend session token). On a fresh install it seeds the distinct ID and marks the user identified. On a returning install where an anonymous user already exists, it merges that user into the identified ID via `identify()`, which emits a `$identify` event during `setup()`. A *different*, already-identified user is left untouched. The identified ID never becomes the device ID.
639
+ - **Bootstrapped flags are served until the first `/flags` response, then replaced.** A complete `/flags` response takes over entirely, so bootstrapped-only keys don't persist past it. Only *enabled* flags are seeded: a `true` boolean or a non-empty variant string. A `false` or empty value is dropped, matching posthog-js. Seed payloads with the separate `featureFlagPayloads` option. Flag values and payloads must be JSON-serializable, or they're dropped. Bootstrapped flags are cleared on `reset()`.
640
+
641
+ The feature-flags-loaded signal fires as soon as bootstrapped flags are applied, so startup logic can read them immediately. These SDKs don't support the `sessionID` bootstrap option.
642
+
643
+ On Flutter web, `bootstrap` is not applied, so configure it in your `posthog.init({...})` snippet instead. See the [bootstrapping guide](/docs/feature-flags/bootstrapping.md) for the cross-SDK overview.
644
+
608
645
  ### Setting properties for flag evaluation
609
646
 
610
647
  If a flag targets person or group properties, you can send those properties inline with the next flag evaluation request instead of waiting for a `$set` event to be ingested. This avoids the race where a flag returns a stale value right after you set a property.
@@ -1,6 +1,6 @@
1
1
  # PostHog Python SDK
2
2
 
3
- **SDK Version:** 7.22.1
3
+ **SDK Version:** 7.25.0
4
4
 
5
5
  Integrate PostHog into any python application.
6
6
 
@@ -73,6 +73,7 @@ Initialize a new PostHog client instance.
73
73
  - **`capture_compression`** (`CaptureCompression`) - Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``"gzip"``/``"deflate"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.
74
74
  - **`secret_key`** (`any`) - A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key="phx_...")
75
75
  - **`_dedicated_ai_endpoint`** (`bool`)
76
+ - **`metrics?`** (`dict`)
76
77
 
77
78
  ### Returns
78
79
 
@@ -259,7 +260,7 @@ posthog.capture('$pageview', distinct_id="distinct_id_of_the_user", properties={
259
260
 
260
261
  **Release Tag:** public
261
262
 
262
- Capture an exception for error tracking.
263
+ Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.
263
264
 
264
265
  ### Parameters
265
266
 
@@ -534,6 +534,41 @@ PostHogSDK.shared.captureFeatureView(flag: "flag-key", flagVariant: "variant-key
534
534
  PostHogSDK.shared.captureFeatureInteraction(flag: "flag-key", flagVariant: "variant-key")
535
535
  ```
536
536
 
537
+ ### Bootstrapping flags
538
+
539
+ Since there is a delay between initializing PostHog and fetching feature flags, feature flags are not always available immediately. This makes them unusable if you want to do something like redirecting a user to a different page based on a feature flag.
540
+
541
+ To have your feature flags available immediately, you can initialize PostHog with precomputed values until it has had a chance to fetch them. This is called bootstrapping. After the SDK fetches feature flags from PostHog, it will use those flag values instead of bootstrapped ones.
542
+
543
+ Set `config.bootstrap` before calling `setup()` to seed identity and flag values before the first `/flags` response (requires iOS SDK `3.66.0`+):
544
+
545
+ Swift
546
+
547
+ PostHog AI
548
+
549
+ ```swift
550
+ let config = PostHogConfig(projectToken: "<ph_project_token>", host: "https://us.i.posthog.com")
551
+ config.bootstrap = PostHogBootstrapConfig(
552
+ distinctId: "distinct_id_of_your_user",
553
+ isIdentifiedId: true,
554
+ featureFlags: [
555
+ "flag-1": true,
556
+ "variant-flag": "control"
557
+ ],
558
+ featureFlagPayloads: nil
559
+ )
560
+ PostHogSDK.shared.setup(config)
561
+ ```
562
+
563
+ - **Bootstrapped identity applies to the first session.** Setting it before `setup()` means events captured synchronously during initialization (like `Application Installed`) carry your distinct ID instead of the SDK-generated UUID.
564
+ - An **anonymous** bootstrap (`isIdentifiedId: false`, the default) seeds the anonymous ID only when none is persisted yet. Once an anonymous ID exists on disk, or the user has been identified, it is ignored.
565
+ - An **identified** bootstrap (`isIdentifiedId: true`) is for a user you've already identified outside the SDK (for example, from a backend session token). On a fresh install it seeds the distinct ID and marks the user identified. On a returning install where an anonymous user already exists, it merges that user into the identified ID via `identify()`, which emits a `$identify` event during `setup()`. A *different*, already-identified user is left untouched. The identified ID never becomes the device ID.
566
+ - **Bootstrapped flags are served until the first `/flags` response, then replaced.** A complete `/flags` response takes over entirely, so bootstrapped-only keys don't persist past it. Only *enabled* flags are seeded: a `true` boolean or a non-empty variant string. A `false` or empty value is dropped, matching posthog-js. Seed payloads with the separate `featureFlagPayloads` option. Flag values and payloads must be JSON-serializable, or they're dropped. Bootstrapped flags are cleared on `reset()`.
567
+
568
+ The feature-flags-loaded signal fires as soon as bootstrapped flags are applied, so startup logic can read them immediately. These SDKs don't support the `sessionID` bootstrap option.
569
+
570
+ See the [bootstrapping guide](/docs/feature-flags/bootstrapping.md) for the cross-SDK overview.
571
+
537
572
  ## Experiments (A/B tests)
538
573
 
539
574
  Since [experiments](/docs/experiments/start-here.md) use feature flags, the code for running an experiment is very similar to the feature flags code. See [adding experiment code](/docs/experiments/adding-experiment-code.md) for iOS examples.
@@ -2,17 +2,15 @@
2
2
  name: neon
3
3
  description: >-
4
4
  Overview of the Neon platform for apps and agents, spanning Postgres, Auth,
5
- Data API, and the new services: Object Storage, Compute Functions, and AI
6
- Gateway. Use whenever "Neon" is mentioned for an overview of how to work with Neon and how to get started. Otherwise, the individual capabilities are the triggers: "object storage" or "S3-compatible
7
- storage", "serverless functions", "background jobs", or
8
- "run code near my database", "AI gateway", "LLM proxy",
9
- "model routing", or "call an LLM" → AI Gateway; "database", "Postgres", or
10
- "authentication" → Postgres and Auth.
5
+ the Data API, and the new services: Object Storage, Compute Functions, and AI
6
+ Gateway. Use when "Neon" is mentioned, or when any of its individual
7
+ capabilities are the trigger: "object storage" or "S3", "buckets", "serverless
8
+ functions", "AI gateway", "call an LLM", "postgres", "database", or "backend".
11
9
  ---
12
10
 
13
11
  # Neon
14
12
 
15
- Important: Neon is no longer just a Serverless Postgres provider. Neon is the backend for apps and agents with Serverless Postgres, Auth, Functions, Storage, and an AI Gateway: instant, branchable, serverless.
13
+ Important: Neon is no longer just a Serverless Postgres provider. Neon is the backend for apps and agents with Serverless Postgres, Auth, Functions, Object Storage, and an AI Gateway: instant, branchable, serverless.
16
14
 
17
15
  Use this skill as the starting point for anything Neon: get an overview of its capabilities, find your way around the Neon agent skills and documentation, and follow best practices for getting started and for branch-first development workflows.
18
16
 
@@ -22,15 +20,15 @@ Neon bundles several backend primitives for building apps and agents that all br
22
20
 
23
21
  - **Postgres** — Serverless Postgres that scales and branches with your app. _Generally available._
24
22
  - **Auth** — Managed authentication with users and sessions stored in Postgres. _Generally available._
25
- - **Object Storage** — S3-compatible object storage that branches with your projects. _Preview / early access._
26
- - **Compute Functions** — Long-running serverless functions running close to your database — for WebSocket servers, long agent HTTP streams, APIs, and server-sent event servers. _Preview / early access._
27
- - **AI Gateway** — One API for all frontier and open-source models, with routing, logging, and cost controls, powered by Databricks. _Preview / early access._
23
+ - **Object Storage** — S3-compatible object storage that branches with your projects. _Public beta._
24
+ - **Functions** — Long-running serverless functions - Neon's compute offering - running close to your database — for WebSocket servers, long agent HTTP streams, APIs, and server-sent event servers. _Public beta._
25
+ - **AI Gateway** — One API for all frontier and open-source models, with routing, logging, and cost controls, powered by Databricks. _Public beta._
28
26
 
29
- ### Preview Service Availability
27
+ ### Public Beta Service Availability
30
28
 
31
- Object Storage, Compute Functions, and AI Gateway are preview (early access) features.
29
+ Object Storage, Functions, and AI Gateway are in public beta.
32
30
 
33
- Early access features are only available on net-new projects created in the `us-east-2` region; they cannot be enabled on existing projects for now. Before guiding a user through any of these services, confirm they are working with a new project in `us-east-2`. If not, they will need to create a new project in that region. Then confirm the user already has early access; otherwise, point them to the private beta sign-up: https://neon.com/blog/were-building-backends#access.
31
+ Beta access features are only available on net-new projects created in the `us-east-2` region; they cannot be enabled on existing projects for now. Before guiding a user through any of these services, confirm they are working with a new project in `us-east-2`. If not, they will need to create a new project in that region.
34
32
 
35
33
  ## Architecture: how Neon fits
36
34
 
@@ -74,7 +72,7 @@ Common doc URLs are organized in the topic links below. If you need a page not l
74
72
  - Choosing or creating the right branch type for dev, preview, test, or CI workflows → `neon-postgres-branches`.
75
73
  - Storing and serving files (uploads, images, blobs) that branch with the database → `neon-object-storage`.
76
74
  - Deploying long-running or streaming serverless functions — APIs, agents, SSE/WebSocket servers — next to the database → `neon-functions`.
77
- - Calling an LLM or routing across model providers with one credential → `neon-ai-gateway`.
75
+ - Calling an LLM or routing across model providers with one credential — including discovering the branch's servable models at runtime via the OpenAI-compatible `/v1/models` endpoint → `neon-ai-gateway`.
78
76
  - Provisioning instant, claimable temporary Postgres databases (for example, one per end user or demo) → `claimable-postgres`.
79
77
  - Diagnosing or fixing excessive Postgres egress (network data-transfer) costs in a codebase → `neon-postgres-egress-optimizer`.
80
78
 
@@ -98,6 +96,8 @@ For example, to install the object storage skill globally for a specific agent w
98
96
  npx skills add neondatabase/agent-skills -s neon-object-storage -g -y -a <agent-name>
99
97
  ```
100
98
 
99
+ You should also make sure the skills are up to date. You can run the same command or replace `add` with `update` to update all Neon skills.
100
+
101
101
  ## Getting Started with Neon
102
102
 
103
103
  Use this section when guiding a user through first-time Neon setup, or when adding a new Neon service (Auth, object storage, functions, and so on) to a project that is already onboarded (for example, one already using Neon Postgres).
@@ -129,7 +129,7 @@ If `init` is not suitable, the individual steps can be run non-interactively, us
129
129
  - **MCP server:** `npx -y add-mcp https://mcp.neon.tech/mcp -g -n Neon -y -a <agent-name>`
130
130
  - **Agent skill:** `npx skills add neondatabase/agent-skills --skill neon-postgres --skill neon --agent <agent-name> -y`
131
131
 
132
- Prefer the CLI over the MCP server unless the user instructs otherwise, since it provides more capabilities, including deploying Neon Functions. For full CLI installation options, see https://neon.com/docs/reference/cli-install.md
132
+ Prefer the CLI over the MCP server unless the user instructs otherwise, since it provides more capabilities, including deploying Neon Functions. For full CLI installation options, see https://neon.com/docs/cli/install.md
133
133
 
134
134
  ### Setup Flow
135
135
 
@@ -178,7 +178,7 @@ If env vars are injected at runtime instead of written to disk — or you simply
178
178
  - `neon-env run -- <your dev command>` (from `@neon/env`) fetches the branch's vars from your `neon.ts` and injects them into the child process at runtime — no `.env` file needed. This is the runtime counterpart to the on-disk `env pull`.
179
179
  - `neon-env export` (from `@neon/env`) prints the branch's env to stdout as dotenv lines or, with `--format json`, JSON — for piping into another env manager rather than running a command. For example, [varlock](https://varlock.dev) can bulk-load it from a `.env.schema` with `@setValuesBulk(exec("neon-env export --format json"), format=json)`.
180
180
  - `fetchEnv` from `@neon/env` is the programmatic version of the same thing: resolve the branch's env in code at runtime instead of shelling out to `neon-env run`.
181
- - `neon dev` injects the same vars into your local dev server — it's part of Neon Functions local development (a private preview feature).
181
+ - `neon dev` injects the same vars into your local dev server — it's part of Neon Functions local development (a public beta feature).
182
182
 
183
183
  When an agent should not write a local `.env`, instruct it (for example in your `AGENTS.md`) to run `neon checkout <branch> --no-env-pull` and rely on runtime injection.
184
184
 
@@ -212,9 +212,13 @@ export default defineConfig({
212
212
  auth: true,
213
213
  dataApi: true,
214
214
  preview: {
215
- functions: { /* ... */ }, // see the neon-functions skill
216
- buckets: { /* ... */ }, // see the neon-object-storage skill
217
- aiGateway: true, // see the neon-ai-gateway skill
215
+ functions: {
216
+ /* ... */
217
+ }, // see the neon-functions skill
218
+ buckets: {
219
+ /* ... */
220
+ }, // see the neon-object-storage skill
221
+ aiGateway: true, // see the neon-ai-gateway skill
218
222
  },
219
223
  });
220
224
  ```
@@ -320,7 +324,10 @@ export default defineConfig({ auth: true, dataApi: true });
320
324
 
321
325
  // 2. Or verify a third-party IdP instead of Neon Auth:
322
326
  export default defineConfig({
323
- dataApi: { authProvider: "external", jwksUrl: "https://your-idp/.well-known/jwks.json" },
327
+ dataApi: {
328
+ authProvider: "external",
329
+ jwksUrl: "https://your-idp/.well-known/jwks.json",
330
+ },
324
331
  });
325
332
  ```
326
333