diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 7ec113b..9d51513 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -12,7 +12,7 @@ "displayName": "PostHog", "source": "./", "description": "Access PostHog analytics, feature flags, experiments, error tracking, and insights directly from your AI coding tool. Optionally capture Claude Code sessions to PostHog LLM Analytics.", - "version": "1.1.60", + "version": "1.1.61", "author": { "name": "PostHog", "email": "hey@posthog.com", diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 12c7a85..9156efc 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "posthog", "description": "Access PostHog analytics, feature flags, experiments, error tracking, and insights directly from your AI coding tool. Optionally capture Claude Code sessions to PostHog LLM Analytics.", - "version": "1.1.60", + "version": "1.1.61", "author": { "name": "PostHog", "email": "hey@posthog.com", diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 42fcf00..375ec8e 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "posthog", - "version": "1.0.58", + "version": "1.0.59", "description": "Access PostHog analytics, feature flags, experiments, error tracking, and insights directly from Codex", "author": { "name": "PostHog", diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index e775d5d..1d01fa8 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "posthog", "displayName": "PostHog", - "version": "1.1.54", + "version": "1.1.55", "description": "Access PostHog analytics, feature flags, experiments, error tracking, and insights directly from Cursor", "author": { "name": "PostHog", diff --git a/gemini-extension.json b/gemini-extension.json index 9e09822..6c3629a 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -1,6 +1,6 @@ { "name": "posthog", - "version": "1.0.56", + "version": "1.0.57", "description": "Access PostHog analytics, feature flags, experiments, error tracking, and insights directly from Gemini CLI", "mcpServers": { "posthog": { diff --git a/skills/instrument-integration/references/flutter.md b/skills/instrument-integration/references/flutter.md index d749a6b..1823cb5 100644 --- a/skills/instrument-integration/references/flutter.md +++ b/skills/instrument-integration/references/flutter.md @@ -184,7 +184,9 @@ Future main() async { #### Web setup -For Web, add your `Web snippet` (which you can find in [your project settings](https://us.posthog.com/settings/project#snippet)) in the `
` of your `web/index.html` file: +If your project has a `web/` directory, this step is required. `Posthog().setup()` is a no-op on web, so a web build without the snippet below captures nothing. + +Add your `Web snippet` (which you can find in [your project settings](https://us.posthog.com/settings/project#snippet)) in the `
` of your `web/index.html` file. Write your project token into the snippet as a literal string. It's public, the same token ships to every visitor, and it needs no build-time or deploy-time injection: web/index.html @@ -292,12 +294,16 @@ PostHog autocapture automatically tracks the following events for you: - **Application Backgrounded** - when the app is sent to the background by the user - **Application Installed** - when the app is installed. - **Application Updated** - when the app is updated. -- **$screen** - when the user navigates (if using [navigatorObservers](https://docs.flutter.dev/ui/navigation) or [go\_router](https://pub.dev/packages/go_router). You'd need to set up the `PosthogObserver` manually.) +- **$screen** - when the user navigates, once you add the `PosthogObserver` - **$exception** - when the app throws exceptions. ### Capturing screen views -> Note: Your routes should be named. Otherwise, they won't be recorded. +Screen views aren't captured automatically. Add the `PosthogObserver` to your app yourself. Without it, your app sends no `$screen` events at all. + +This works with any routing package, not just the plain `Navigator` API. Add the observer wherever your router takes navigator observers, as shown below for `MaterialApp` and `go_router`. + +> Note: Screen names come from each route's `RouteSettings.name`. Most routing packages set this for you. If yours doesn't, name your routes so `$screen` events are readable. #### Using `navigatorObservers` diff --git a/skills/instrument-integration/references/posthog-node.md b/skills/instrument-integration/references/posthog-node.md index b85e9a1..f94c067 100644 --- a/skills/instrument-integration/references/posthog-node.md +++ b/skills/instrument-integration/references/posthog-node.md @@ -1011,13 +1011,13 @@ await client.enable() Evaluate all feature flags for a user in a single call and return a snapshot. Branch on `.isEnabled()` / `.getFlag()`, then pass the same snapshot to `capture()` via the `flags` option so the captured event carries the exact flag values the code branched on. Prefer this over repeated `isFeatureEnabled()` / `getFeatureFlag()` calls and over `capture({ sendFeatureFlags: true })` — it consolidates flag evaluation into a single `/flags` request per incoming request. -**Local evaluation is transparent.** When the poller can resolve a flag from cached definitions, no network call is made and the snapshot's `$feature_flag_called` events are tagged `locally_evaluated: true`. -**Trim the request.** Pass `flagKeys` to scope the underlying `/flags` request to a subset of flags — useful when you only need a few flags and want to reduce the response payload. +**Local evaluation is transparent.** When the poller can resolve a flag from cached definitions, no network call is made and the snapshot's `$feature_flag_called` events are tagged `locally_evaluated: true`. A requested key missing from local definitions is included in a `/flags` fallback unless `onlyEvaluateLocally` is true. Locally resolved values remain authoritative when remote results are merged. +**Trim the request.** Pass `flagKeys` to scope local evaluation, the underlying `/flags` request, and the returned snapshot to a subset of flags. Remote evaluation responses are not cached, so a key missing both locally and remotely costs one `/flags` request per `evaluateFlags()` call. **Trim the event payload.** Use `flags.only([...])` or `flags.onlyAccessed()` to filter which flags get attached to a captured event without re-fetching. ### Parameters -- **`options?`** (`AllFlagsOptions`) - Optional configuration for flag evaluation. Supports the same fields as `getAllFlags()`, including `flagKeys` to scope the `/flags` request. +- **`options?`** (`AllFlagsOptions`) - Optional configuration for flag evaluation. Supports the same fields as `getAllFlags()`. `flagKeys` scopes local evaluation, the `/flags` request, and the returned snapshot. `onlyEvaluateLocally` prevents fallback and leaves unresolved keys absent. ### Returns diff --git a/skills/instrument-integration/references/posthog-python.md b/skills/instrument-integration/references/posthog-python.md index ae3cd3a..7fe75f6 100644 --- a/skills/instrument-integration/references/posthog-python.md +++ b/skills/instrument-integration/references/posthog-python.md @@ -2,7 +2,7 @@ # PostHog Python SDK -**SDK Version:** 7.39.2 +**SDK Version:** 7.43.0 Integrate PostHog into any python application. @@ -320,7 +320,7 @@ Evaluate all feature flags for a user in a single call and return a :class:`Feat - **`group_properties?`** (`dict[str, dict[str, Any]]`) - Group properties keyed by group type. - **`only_evaluate_locally`** (`bool`) - If True, never fall back to remote evaluation — flags that can't be evaluated locally are simply omitted from the snapshot. - **`disable_geoip?`** (`bool`) - Whether to disable GeoIP lookup. -- **`flag_keys?`** (`list[str]`) - Optional list of flag keys to scope the underlying ``/flags`` request to a subset. +- **`flag_keys?`** (`list[str]`) - Optional non-empty list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. An empty list is treated like ``None`` and evaluates all flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot. - **`device_id?`** (`str`) - Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes. ### Returns @@ -1166,9 +1166,9 @@ Evaluate all feature flags for a user in a single call and return a :class:`Feat - **`groups?`** (`Mapping[str, Union[str, int]]`) - Mapping of group type to group key. - **`person_properties?`** (`dict[str, Any]`) - Person properties to use for evaluation. - **`group_properties?`** (`dict[str, dict[str, Any]]`) - Group properties keyed by group type. -- **`only_evaluate_locally`** (`bool`) - If ``True``, never fall back to remote evaluation. +- **`only_evaluate_locally`** (`bool`) - If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally. - **`disable_geoip?`** (`bool`) - Whether to disable GeoIP lookup. -- **`flag_keys?`** (`list[str]`) - Optional list of flag keys. When provided, only these flags are evaluated — the underlying ``/flags`` request asks the server for just this subset, which makes the response smaller and the request cheaper. Use this when you only need a handful of flags out of many. +- **`flag_keys?`** (`list[str]`) - Optional non-empty list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. An empty list is treated like ``None`` and evaluates all flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot. - **`device_id?`** (`str`) - Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes. ### Returns diff --git a/skills/instrument-llm-analytics/references/manual-capture.md b/skills/instrument-llm-analytics/references/manual-capture.md index 15b352e..d4b826f 100644 --- a/skills/instrument-llm-analytics/references/manual-capture.md +++ b/skills/instrument-llm-analytics/references/manual-capture.md @@ -444,6 +444,10 @@ Skip the manual setup — run this in your project and the wizard installs the S | [Spans](/docs/ai-observability/spans.md) | Review spans and their role in representing individual operations. | | [Anaylze LLM performance](/docs/ai-observability/dashboard.md) | Learn how to create dashboards to analyze LLM performance. | +## Large events + +For large events, use the dedicated AI ingestion path – see [capturing large AI events](/docs/ai-observability/large-events.md). + ### Still have questions? Ask PostHog AI diff --git a/skills/instrument-logs/references/flutter.md b/skills/instrument-logs/references/flutter.md index 04ae732..1d6f33e 100644 --- a/skills/instrument-logs/references/flutter.md +++ b/skills/instrument-logs/references/flutter.md @@ -192,7 +192,9 @@ The PostHog Flutter SDK has built-in support for capturing structured Logs from #### Web setup - For Web, add your `Web snippet` (which you can find in [your project settings](https://us.posthog.com/settings/project#snippet)) in the `
` of your `web/index.html` file: + If your project has a `web/` directory, this step is required. `Posthog().setup()` is a no-op on web, so a web build without the snippet below captures nothing. + + Add your `Web snippet` (which you can find in [your project settings](https://us.posthog.com/settings/project#snippet)) in the `
` of your `web/index.html` file. Write your project token into the snippet as a literal string. It's public, the same token ships to every visitor, and it needs no build-time or deploy-time injection: web/index.html diff --git a/skills/instrument-product-analytics/references/flutter.md b/skills/instrument-product-analytics/references/flutter.md index d749a6b..1823cb5 100644 --- a/skills/instrument-product-analytics/references/flutter.md +++ b/skills/instrument-product-analytics/references/flutter.md @@ -184,7 +184,9 @@ Future main() async { #### Web setup -For Web, add your `Web snippet` (which you can find in [your project settings](https://us.posthog.com/settings/project#snippet)) in the `
` of your `web/index.html` file: +If your project has a `web/` directory, this step is required. `Posthog().setup()` is a no-op on web, so a web build without the snippet below captures nothing. + +Add your `Web snippet` (which you can find in [your project settings](https://us.posthog.com/settings/project#snippet)) in the `
` of your `web/index.html` file. Write your project token into the snippet as a literal string. It's public, the same token ships to every visitor, and it needs no build-time or deploy-time injection: web/index.html @@ -292,12 +294,16 @@ PostHog autocapture automatically tracks the following events for you: - **Application Backgrounded** - when the app is sent to the background by the user - **Application Installed** - when the app is installed. - **Application Updated** - when the app is updated. -- **$screen** - when the user navigates (if using [navigatorObservers](https://docs.flutter.dev/ui/navigation) or [go\_router](https://pub.dev/packages/go_router). You'd need to set up the `PosthogObserver` manually.) +- **$screen** - when the user navigates, once you add the `PosthogObserver` - **$exception** - when the app throws exceptions. ### Capturing screen views -> Note: Your routes should be named. Otherwise, they won't be recorded. +Screen views aren't captured automatically. Add the `PosthogObserver` to your app yourself. Without it, your app sends no `$screen` events at all. + +This works with any routing package, not just the plain `Navigator` API. Add the observer wherever your router takes navigator observers, as shown below for `MaterialApp` and `go_router`. + +> Note: Screen names come from each route's `RouteSettings.name`. Most routing packages set this for you. If yours doesn't, name your routes so `$screen` events are readable. #### Using `navigatorObservers` diff --git a/skills/instrument-product-analytics/references/posthog-python.md b/skills/instrument-product-analytics/references/posthog-python.md index ae3cd3a..7fe75f6 100644 --- a/skills/instrument-product-analytics/references/posthog-python.md +++ b/skills/instrument-product-analytics/references/posthog-python.md @@ -2,7 +2,7 @@ # PostHog Python SDK -**SDK Version:** 7.39.2 +**SDK Version:** 7.43.0 Integrate PostHog into any python application. @@ -320,7 +320,7 @@ Evaluate all feature flags for a user in a single call and return a :class:`Feat - **`group_properties?`** (`dict[str, dict[str, Any]]`) - Group properties keyed by group type. - **`only_evaluate_locally`** (`bool`) - If True, never fall back to remote evaluation — flags that can't be evaluated locally are simply omitted from the snapshot. - **`disable_geoip?`** (`bool`) - Whether to disable GeoIP lookup. -- **`flag_keys?`** (`list[str]`) - Optional list of flag keys to scope the underlying ``/flags`` request to a subset. +- **`flag_keys?`** (`list[str]`) - Optional non-empty list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. An empty list is treated like ``None`` and evaluates all flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot. - **`device_id?`** (`str`) - Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes. ### Returns @@ -1166,9 +1166,9 @@ Evaluate all feature flags for a user in a single call and return a :class:`Feat - **`groups?`** (`Mapping[str, Union[str, int]]`) - Mapping of group type to group key. - **`person_properties?`** (`dict[str, Any]`) - Person properties to use for evaluation. - **`group_properties?`** (`dict[str, dict[str, Any]]`) - Group properties keyed by group type. -- **`only_evaluate_locally`** (`bool`) - If ``True``, never fall back to remote evaluation. +- **`only_evaluate_locally`** (`bool`) - If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally. - **`disable_geoip?`** (`bool`) - Whether to disable GeoIP lookup. -- **`flag_keys?`** (`list[str]`) - Optional list of flag keys. When provided, only these flags are evaluated — the underlying ``/flags`` request asks the server for just this subset, which makes the response smaller and the request cheaper. Use this when you only need a handful of flags out of many. +- **`flag_keys?`** (`list[str]`) - Optional non-empty list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. An empty list is treated like ``None`` and evaluates all flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot. - **`device_id?`** (`str`) - Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes. ### Returns