diff --git a/context/agents/README.md b/context/agents/README.md new file mode 100644 index 00000000..0737511d --- /dev/null +++ b/context/agents/README.md @@ -0,0 +1,37 @@ +# Agent prompts + +One `.md` per orchestrator task — the WHAT of the task. The frontmatter +carries the artifacts the executor configures the run with: the model, the +mini-skills to load (the HOW), the tools the task may and may not use, and the +tasks it depends on. `flow` names the program the agent belongs to — the +wizard's registry is scoped per flow, so audit or migration agents live +alongside these — and one prompt per flow is marked `seed: true`: the planner +that seeds the queue, not an enqueueable task type. + +The body is intent only — what to do and what done looks like. The client +injects the basics (project context, how to report, how to surface progress), +so a prompt never restates them. + +This README is documentation, not data: the build serves every other `.md` in +this folder as an agent prompt. + +```markdown +--- +type: example +flow: my-flow +model: claude-haiku-4-5-20251001 +skills: [] +allowedTools: [Read, Glob, Grep] +disallowedTools: [enqueue_task] +dependsOn: [] +--- + +## Goal + +What this task does, in plain prose. + +## How you know you succeeded + +Plain-text success criteria live here. State what done looks like, and what to +do when the task cannot be completed. +``` diff --git a/context/agents/build.md b/context/agents/build.md new file mode 100644 index 00000000..77243bab --- /dev/null +++ b/context/agents/build.md @@ -0,0 +1,25 @@ +--- +type: build +flow: posthog-integration +label: Install dependencies and build +model: claude-sonnet-4-6 +skills: [basic-integration-build] +allowedTools: [Read, Edit, Glob, Grep, Bash] +disallowedTools: [enqueue_task] +dependsOn: [install, init, identify, error-tracking, capture] +--- + +## Goal + +Bring the integration together: install the dependencies the earlier steps +declared, then verify the project builds, lints, and passes its tests. Until now +the steps only edited code and the manifest — this is where it actually installs +and is checked. + +## How you know you succeeded + +The install completes and the build, lint, and tests pass. If you hit a conflict +you cannot cleanly resolve — a dependency clash, a build error from the new code — +fix what you safely can, then report it: put a one-line summary in your handoff's +`conflict` field and the full detail in what you did. The user sees the one-liner +in the outro and the detail in the report. diff --git a/context/agents/capture.md b/context/agents/capture.md new file mode 100644 index 00000000..db5a77c4 --- /dev/null +++ b/context/agents/capture.md @@ -0,0 +1,22 @@ +--- +type: capture +flow: posthog-integration +label: Capture events +model: claude-sonnet-4-6 +skills: [basic-integration-capture] +allowedTools: [Read, Edit, Glob, Grep] +disallowedTools: [enqueue_task] +dependsOn: [install, init] +--- + +## Goal + +Decide which events are worth capturing in this app, then instrument them in the +same pass — read each file once, choose the events, and add the capture calls +while the file is already open. + +## How you know you succeeded + +The meaningful user actions across the app have capture calls that fire on the +real action, not on page load, and `.posthog-wizard-cache/.posthog-events.json` +lists the events you instrumented. diff --git a/context/agents/dashboard.md b/context/agents/dashboard.md new file mode 100644 index 00000000..54c336de --- /dev/null +++ b/context/agents/dashboard.md @@ -0,0 +1,20 @@ +--- +type: dashboard +flow: posthog-integration +label: Create a starter dashboard +model: claude-sonnet-4-6 +skills: [basic-integration-dashboard] +allowedTools: [Read, Glob, Grep] +disallowedTools: [Write, Edit, Bash, enqueue_task] +dependsOn: [build] +--- + +## Goal + +Create a starter PostHog dashboard with a few insights built on the events this +integration instruments, using the PostHog MCP. + +## How you know you succeeded + +A dashboard exists with a handful of insights on the captured events, and you hand +off its URL for the report to link. diff --git a/context/agents/error-tracking.md b/context/agents/error-tracking.md new file mode 100644 index 00000000..c7e2aea3 --- /dev/null +++ b/context/agents/error-tracking.md @@ -0,0 +1,28 @@ +--- +type: error-tracking +flow: posthog-integration +label: Add error tracking +model: claude-sonnet-4-6 +skills: [basic-integration-error-tracking-step] +allowedTools: [Read, Write, Edit, Glob, Grep] +disallowedTools: [enqueue_task] +dependsOn: [install, init] +--- + +## Goal + +Set up the framework's single global error boundary so uncaught errors reach +PostHog. One place — the init or app entry — following the docs and the reference +example, not manual capture calls sprinkled across files. The SDK is already +installed and initialized (see the context from previous steps); build on that, +do not re-check it. + +This is an instrument-only task. Do not install dependencies, run the build, run +tests, or start the app — a later `build` step does all verification. Stay inside +this project's directory and edit the one global handler; that is the whole job. + +## How you know you succeeded + +A global error handler forwards exceptions to PostHog. You did not install +anything, run a build or tests, search outside the project, or read through the +whole app or hand-wrap individual components or routes. diff --git a/context/agents/identify.md b/context/agents/identify.md new file mode 100644 index 00000000..658afca9 --- /dev/null +++ b/context/agents/identify.md @@ -0,0 +1,20 @@ +--- +type: identify +flow: posthog-integration +label: Wire user identification +model: claude-sonnet-4-6 +skills: [basic-integration-identify] +allowedTools: [Read, Edit, Glob, Grep] +disallowedTools: [enqueue_task] +dependsOn: [install, init] +--- + +## Goal + +Wire user identification: call PostHog identify wherever the app establishes who +the user is, typically at login and signup. + +## How you know you succeeded + +An identify call fires at the point the user becomes known, with a stable +distinct id. If the app has no auth or user concept, say so and stop. diff --git a/context/agents/init.md b/context/agents/init.md new file mode 100644 index 00000000..ffc62c2d --- /dev/null +++ b/context/agents/init.md @@ -0,0 +1,21 @@ +--- +type: init +flow: posthog-integration +label: Set up PostHog initialization +model: claude-haiku-4-5-20251001 +skills: [basic-integration-init] +allowedTools: [Read, Write, Edit, Glob, Grep] +disallowedTools: [enqueue_task] +dependsOn: [] +--- + +## Goal + +Initialize PostHog: create the framework's init point so the SDK is configured +once and available across the app, and set the PostHog environment variables +through the wizard tools. + +## How you know you succeeded + +The init file exists and the PostHog env keys are present. Keys live in the env +file, never hardcoded in source. diff --git a/context/agents/install.md b/context/agents/install.md new file mode 100644 index 00000000..4ed83e18 --- /dev/null +++ b/context/agents/install.md @@ -0,0 +1,21 @@ +--- +type: install +flow: posthog-integration +label: Add the PostHog SDK to the manifest +model: claude-haiku-4-5-20251001 +skills: [basic-integration-install] +allowedTools: [Read, Edit, Glob, Grep] +disallowedTools: [enqueue_task] +dependsOn: [] +--- + +## Goal + +Declare the PostHog SDK in the project's package manifest. Do not run the package +manager and do not build — the build task installs and verifies everything at the +end. + +## How you know you succeeded + +The SDK is listed in the manifest's dependencies at a sensible version. If it is +already declared, leave it and say so. diff --git a/context/agents/integrate-posthog.md b/context/agents/integrate-posthog.md new file mode 100644 index 00000000..904ef74f --- /dev/null +++ b/context/agents/integrate-posthog.md @@ -0,0 +1,31 @@ +--- +type: integrate-posthog +flow: posthog-integration +seed: true +model: claude-sonnet-4-6 +skills: [] +allowedTools: [Read, Glob, Grep] +disallowedTools: [Write, Edit, Bash, complete_task] +dependsOn: [] +--- + +## Goal + +Plan a PostHog integration and seed the task queue with this graph: + +- `install` and `init`, independent of each other. +- `identify`, `capture`, and `error-tracking`, each after `install` and `init` + and independent of one another, so they run in parallel. `capture` decides the + events and instruments them; `error-tracking` wires the single global error + boundary — it needs the SDK installed and initialized, not the events. +- `build`, after `install`, `init`, `identify`, `capture`, and `error-tracking` — + it installs the dependencies and verifies the project builds, lints, and passes + its tests. +- `dashboard`, after `build` — only once the integration is confirmed building, + linting, and testing cleanly. +- `report`, after `dashboard` — it writes the setup report last. + +## How you know you succeeded + +Every task in the graph is queued with that dependency shape, the report last, +and the first task runnable. Keep labels short — the action in a few words. diff --git a/context/agents/report.md b/context/agents/report.md new file mode 100644 index 00000000..d9db8a69 --- /dev/null +++ b/context/agents/report.md @@ -0,0 +1,23 @@ +--- +type: report +flow: posthog-integration +label: Write the setup report +model: claude-sonnet-4-6 +skills: [basic-integration-report] +allowedTools: [Read, Write, Glob, Grep] +disallowedTools: [enqueue_task] +dependsOn: [dashboard] +--- + +## Goal + +Write the setup report summarizing what this integration did, drawing only on the +run's queue log and event plan in `.posthog-wizard-cache/` (`queue.json` and +`.posthog-events.json`). + +## How you know you succeeded + +`posthog-setup-report.md` exists at the project root: what was installed and +initialized, the events captured, whether identify was wired or skipped, error +tracking added, the dashboard link, any build conflict in full, and the next +steps for the user. diff --git a/context/docs.yaml b/context/docs.yaml index 1ca6752d..4e29e14e 100644 --- a/context/docs.yaml +++ b/context/docs.yaml @@ -8,6 +8,7 @@ docs: tags: [core, users, identity] urls: - https://posthog.com/docs/getting-started/identify-users.md + - https://posthog.com/docs/product-analytics/identity-resolution.md - id: cloudflare-workers display_name: Cloudflare Workers diff --git a/context/skills/basic-integration/build/config.yaml b/context/skills/basic-integration/build/config.yaml new file mode 100644 index 00000000..82142d68 --- /dev/null +++ b/context/skills/basic-integration/build/config.yaml @@ -0,0 +1,9 @@ +type: docs-only +template: description.md +description: Install dependencies and verify the project builds +tags: [orchestrator, build] +variants: + - id: all + display_name: PostHog build step + tags: [orchestrator, build] + docs_urls: [] diff --git a/context/skills/basic-integration/build/description.md b/context/skills/basic-integration/build/description.md new file mode 100644 index 00000000..aa9356cf --- /dev/null +++ b/context/skills/basic-integration/build/description.md @@ -0,0 +1,35 @@ +# Install and build + +Install the declared dependencies, then verify the project builds. Be quick and +decisive — this step must not spiral. + +## Install + +Detect the package manager from the project's lockfile and run its install once, +in this project directory. The manifest already declares PostHog. If install is +slow, errors, or can't resolve a package, do not retry with offline flags and do +not poke the package manager's global store or cache — a failed install is a +conflict to report (below), not a problem to fight. + +## Build and verify + +Run the project's build (or typecheck), lint, and test scripts if they exist +(check the manifest's scripts). Only errors in the files this integration changed +are yours to fix — a missing import, a wrong call shape. +An error in a file the integration never touched is pre-existing: note it and +move on (below). Do not re-run build, typecheck, or lint hoping a pre-existing +failure clears — it will not, and each re-run is slow. + +## Flag out-of-scope conflicts and move on + +Work only inside this project's own directory. Never read, search, or write +anywhere outside it — not other repos, not the OS, not the package manager's +global store or cache. + +A build or install you can't cleanly finish is a perfectly acceptable outcome — +**as long as you report it.** If you hit a conflict that is excessively difficult +or outside the scope of this integration — a dependency clash, a pre-existing +build break, an install that won't resolve, an environment issue unrelated to the +PostHog code — stop fighting it: put a one-line summary in your handoff `conflict` +field and the full detail in `did`, then complete the task. The user sees it in +the outro and the report; reporting it and moving on is the right outcome. diff --git a/context/skills/basic-integration/capture/config.yaml b/context/skills/basic-integration/capture/config.yaml new file mode 100644 index 00000000..618bc884 --- /dev/null +++ b/context/skills/basic-integration/capture/config.yaml @@ -0,0 +1,383 @@ +type: docs-only +template: description.md +description: Instrument the planned events with PostHog capture calls +tags: + - orchestrator + - capture +shared_docs: + - https://posthog.com/docs/product-analytics/best-practices.md +variants: + - id: nextjs-app-router + display_name: Next.js App Router + tags: + - orchestrator + - capture + - nextjs + - react + - ssr + - app-router + - javascript + docs_urls: + - https://posthog.com/docs/libraries/next-js.md + - id: nextjs-pages-router + display_name: Next.js Pages Router + tags: + - orchestrator + - capture + - nextjs + - react + - ssr + - pages-router + - javascript + docs_urls: + - https://posthog.com/docs/libraries/next-js.md + - id: react-react-router-6 + display_name: React Router v6 + tags: + - orchestrator + - capture + - react + - react-router + - v6 + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v6.md + - id: react-react-router-7-framework + display_name: React Router v7 - Framework mode + tags: + - orchestrator + - capture + - react + - react-router + - v7 + - framework + - ssr + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v7-framework-mode.md + - id: react-react-router-7-data + display_name: React Router v7 - Data mode + tags: + - orchestrator + - capture + - react + - react-router + - v7 + - data + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v7-data-mode.md + - id: react-react-router-7-declarative + display_name: React Router v7 - Declarative mode + tags: + - orchestrator + - capture + - react + - react-router + - v7 + - declarative + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v7-declarative-mode.md + - id: react-vite + display_name: React (Vite) + tags: + - orchestrator + - capture + - react + - vite + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react.md + - id: nuxt-3-6 + display_name: Nuxt 3.6 + tags: + - orchestrator + - capture + - nuxt + - javascript + docs_urls: + - https://posthog.com/docs/libraries/nuxt-js-3-6.md + - id: nuxt-4 + display_name: Nuxt 4 + tags: + - orchestrator + - capture + - nuxt + - vue + - ssr + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/nuxt-js.md + - id: vue-3 + display_name: Vue 3 + tags: + - orchestrator + - capture + - vue + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/vue-js.md + - id: django + display_name: Django + tags: + - orchestrator + - capture + - django + - python + docs_urls: + - https://posthog.com/docs/libraries/django.md + - id: flask + display_name: Flask + tags: + - orchestrator + - capture + - flask + - python + docs_urls: + - https://posthog.com/docs/libraries/flask.md + - id: fastapi + display_name: FastAPI + tags: + - orchestrator + - capture + - fastapi + - python + docs_urls: + - https://posthog.com/docs/libraries/python.md + - id: react-tanstack-router-file-based + display_name: React with TanStack Router (file-based) + tags: + - orchestrator + - capture + - react + - tanstack-router + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/tanstack-start.md + - id: react-tanstack-router-code-based + display_name: React with TanStack Router (code-based) + tags: + - orchestrator + - capture + - react + - tanstack-router + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/tanstack-start.md + - id: tanstack-start + display_name: TanStack Start + tags: + - orchestrator + - capture + - react + - tanstack-start + - tanstack-router + - javascript + docs_urls: + - https://posthog.com/docs/libraries/tanstack-start.md + - id: laravel + display_name: Laravel + tags: + - orchestrator + - capture + - laravel + - php + docs_urls: + - https://posthog.com/docs/libraries/laravel.md + - id: php + display_name: PHP + tags: + - orchestrator + - capture + - php + docs_urls: + - https://posthog.com/docs/libraries/php.md + - id: ruby-on-rails + display_name: Ruby on Rails + tags: + - orchestrator + - capture + - ruby-on-rails + - ruby + docs_urls: + - https://posthog.com/docs/libraries/ruby-on-rails.md + - https://posthog.com/docs/libraries/ruby.md + - id: android + display_name: Android + tags: + - orchestrator + - capture + - android + - java + - kotlin + docs_urls: + - https://posthog.com/docs/libraries/android.md + - id: sveltekit + display_name: SvelteKit + tags: + - orchestrator + - capture + - sveltekit + - svelte + - javascript + docs_urls: + - https://posthog.com/docs/libraries/svelte.md + - id: python + display_name: Python + tags: + - orchestrator + - capture + - python + docs_urls: + - https://posthog.com/docs/libraries/python.md + - https://posthog.com/docs/references/posthog-python.md + - id: javascript_node + display_name: JavaScript Node + tags: + - orchestrator + - capture + - javascript_node + docs_urls: + - https://posthog.com/docs/libraries/node.md + - https://posthog.com/docs/references/posthog-node.md + - id: javascript_web + display_name: JavaScript Web + tags: + - orchestrator + - capture + - javascript_web + docs_urls: + - https://posthog.com/docs/libraries/js.md + - https://posthog.com/docs/references/posthog-js.md + - id: ruby + display_name: Ruby + tags: + - orchestrator + - capture + - ruby + docs_urls: + - https://posthog.com/docs/libraries/ruby.md + - id: elixir + display_name: Elixir + tags: + - orchestrator + - capture + - elixir + - phoenix + - plug + docs_urls: + - https://posthog.com/docs/libraries/elixir.md + - id: go + display_name: Go + tags: + - orchestrator + - capture + - go + docs_urls: + - https://posthog.com/docs/libraries/go.md + - id: swift + display_name: Swift (iOS/macOS) + tags: + - orchestrator + - capture + - swift + - ios + - macos + - swiftui + docs_urls: + - https://posthog.com/docs/libraries/ios.md + - https://posthog.com/docs/libraries/ios/usage.md + - https://posthog.com/docs/libraries/ios/configuration.md + - id: flutter + display_name: Flutter + tags: + - orchestrator + - capture + - flutter + - dart + - mobile + docs_urls: + - https://posthog.com/docs/libraries/flutter.md + - id: react-native + display_name: React Native + tags: + - orchestrator + - capture + - react-native + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/react-native.md + - id: expo + display_name: Expo + tags: + - orchestrator + - capture + - expo + - react-native + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/react-native.md + - id: astro-static + display_name: Astro (Static) + tags: + - orchestrator + - capture + - astro + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: astro-view-transitions + display_name: Astro (View Transitions) + tags: + - orchestrator + - capture + - astro + - astro-view-transitions + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: astro-ssr + display_name: Astro (SSR) + tags: + - orchestrator + - capture + - astro + - astro-ssr + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: astro-hybrid + display_name: Astro (Hybrid) + tags: + - orchestrator + - capture + - astro + - astro-hybrid + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: angular + display_name: Angular + tags: + - orchestrator + - capture + - angular + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/angular.md diff --git a/context/skills/basic-integration/capture/description.md b/context/skills/basic-integration/capture/description.md new file mode 100644 index 00000000..b0a7d1b7 --- /dev/null +++ b/context/skills/basic-integration/capture/description.md @@ -0,0 +1,42 @@ +# Plan and capture events + +Decide which custom events are worth capturing, then instrument them — in one +pass, reading each file once. + +## Choose and record + +From the project's files, select between 10 and 15 that might have business value +for event tracking — especially conversion and churn events. Read them. Track +actions, not pageviews (autocapture covers those). Server-side events are required +if there is instrumentable server-side code (API routes, server actions): +payment/checkout completion, webhook handlers, and auth endpoints. + +First scan for capture calls the project already makes, and note how their event +names are formatted. Event names, property names, and feature flag keys are an +analytics contract: reuse the existing names and follow the patterns already in +the project rather than inventing parallel ones, and don't duplicate events that +already exist. + +Write the chosen events to `.posthog-wizard-cache/.posthog-events.json` — a JSON +array of `{ event, description, file }`, one entry per event. That cache directory +is the wizard's, already created for the run; write the plan there, not at the +project root. Write it before you start editing: it drives the event-plan view, +and it is the source the report reads later. + +## Instrument + +For each event call the SDK's capture method on the real user action — the click +or submit handler, the server action — not on render or page load. Use clear +`lower_snake_case` names and useful properties. Edit each file while it is already +open. + +Server-side, use the authenticated user's id as the distinct id. For a genuinely +unauthenticated action, emit a personless event — never fabricate a placeholder +id like `'anonymous'`, which collapses every anonymous user into one person and +corrupts the data. + +Leave `.posthog-wizard-cache/.posthog-events.json` in place for the report. + +## Reference + +{references} diff --git a/context/skills/basic-integration/dashboard/config.yaml b/context/skills/basic-integration/dashboard/config.yaml new file mode 100644 index 00000000..affa5328 --- /dev/null +++ b/context/skills/basic-integration/dashboard/config.yaml @@ -0,0 +1,9 @@ +type: docs-only +template: description.md +description: Create a starter PostHog dashboard from the captured events +tags: [orchestrator, dashboard] +variants: + - id: all + display_name: PostHog dashboard step + tags: [orchestrator, dashboard] + docs_urls: [] diff --git a/context/skills/basic-integration/dashboard/description.md b/context/skills/basic-integration/dashboard/description.md new file mode 100644 index 00000000..71e580c5 --- /dev/null +++ b/context/skills/basic-integration/dashboard/description.md @@ -0,0 +1,11 @@ +# Create a starter dashboard + +Use the PostHog MCP tools to create a dashboard named "Analytics basics (wizard)" +with a few high-signal insights built on the events this integration captures. + +- Read the capture step's handoff for the exact event names — use the real names, + do not invent events that were not instrumented. +- Add up to five insights, favoring conversion funnels and the events that signal + activation or churn. + +Hand off the dashboard URL so the report can link to it. diff --git a/context/skills/basic-integration/error-tracking-step/config.yaml b/context/skills/basic-integration/error-tracking-step/config.yaml new file mode 100644 index 00000000..9cb1076e --- /dev/null +++ b/context/skills/basic-integration/error-tracking-step/config.yaml @@ -0,0 +1,381 @@ +type: docs-only +template: description.md +description: Capture exceptions with PostHog around critical flows +tags: + - orchestrator + - error-tracking +variants: + - id: nextjs-app-router + display_name: Next.js App Router + tags: + - orchestrator + - error-tracking + - nextjs + - react + - ssr + - app-router + - javascript + docs_urls: + - https://posthog.com/docs/libraries/next-js.md + - id: nextjs-pages-router + display_name: Next.js Pages Router + tags: + - orchestrator + - error-tracking + - nextjs + - react + - ssr + - pages-router + - javascript + docs_urls: + - https://posthog.com/docs/libraries/next-js.md + - id: react-react-router-6 + display_name: React Router v6 + tags: + - orchestrator + - error-tracking + - react + - react-router + - v6 + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v6.md + - id: react-react-router-7-framework + display_name: React Router v7 - Framework mode + tags: + - orchestrator + - error-tracking + - react + - react-router + - v7 + - framework + - ssr + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v7-framework-mode.md + - id: react-react-router-7-data + display_name: React Router v7 - Data mode + tags: + - orchestrator + - error-tracking + - react + - react-router + - v7 + - data + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v7-data-mode.md + - id: react-react-router-7-declarative + display_name: React Router v7 - Declarative mode + tags: + - orchestrator + - error-tracking + - react + - react-router + - v7 + - declarative + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v7-declarative-mode.md + - id: react-vite + display_name: React (Vite) + tags: + - orchestrator + - error-tracking + - react + - vite + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react.md + - id: nuxt-3-6 + display_name: Nuxt 3.6 + tags: + - orchestrator + - error-tracking + - nuxt + - javascript + docs_urls: + - https://posthog.com/docs/libraries/nuxt-js-3-6.md + - id: nuxt-4 + display_name: Nuxt 4 + tags: + - orchestrator + - error-tracking + - nuxt + - vue + - ssr + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/nuxt-js.md + - id: vue-3 + display_name: Vue 3 + tags: + - orchestrator + - error-tracking + - vue + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/vue-js.md + - id: django + display_name: Django + tags: + - orchestrator + - error-tracking + - django + - python + docs_urls: + - https://posthog.com/docs/libraries/django.md + - id: flask + display_name: Flask + tags: + - orchestrator + - error-tracking + - flask + - python + docs_urls: + - https://posthog.com/docs/libraries/flask.md + - id: fastapi + display_name: FastAPI + tags: + - orchestrator + - error-tracking + - fastapi + - python + docs_urls: + - https://posthog.com/docs/libraries/python.md + - id: react-tanstack-router-file-based + display_name: React with TanStack Router (file-based) + tags: + - orchestrator + - error-tracking + - react + - tanstack-router + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/tanstack-start.md + - id: react-tanstack-router-code-based + display_name: React with TanStack Router (code-based) + tags: + - orchestrator + - error-tracking + - react + - tanstack-router + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/tanstack-start.md + - id: tanstack-start + display_name: TanStack Start + tags: + - orchestrator + - error-tracking + - react + - tanstack-start + - tanstack-router + - javascript + docs_urls: + - https://posthog.com/docs/libraries/tanstack-start.md + - id: laravel + display_name: Laravel + tags: + - orchestrator + - error-tracking + - laravel + - php + docs_urls: + - https://posthog.com/docs/libraries/laravel.md + - id: php + display_name: PHP + tags: + - orchestrator + - error-tracking + - php + docs_urls: + - https://posthog.com/docs/libraries/php.md + - id: ruby-on-rails + display_name: Ruby on Rails + tags: + - orchestrator + - error-tracking + - ruby-on-rails + - ruby + docs_urls: + - https://posthog.com/docs/libraries/ruby-on-rails.md + - https://posthog.com/docs/libraries/ruby.md + - id: android + display_name: Android + tags: + - orchestrator + - error-tracking + - android + - java + - kotlin + docs_urls: + - https://posthog.com/docs/libraries/android.md + - id: sveltekit + display_name: SvelteKit + tags: + - orchestrator + - error-tracking + - sveltekit + - svelte + - javascript + docs_urls: + - https://posthog.com/docs/libraries/svelte.md + - id: python + display_name: Python + tags: + - orchestrator + - error-tracking + - python + docs_urls: + - https://posthog.com/docs/libraries/python.md + - https://posthog.com/docs/references/posthog-python.md + - id: javascript_node + display_name: JavaScript Node + tags: + - orchestrator + - error-tracking + - javascript_node + docs_urls: + - https://posthog.com/docs/libraries/node.md + - https://posthog.com/docs/references/posthog-node.md + - id: javascript_web + display_name: JavaScript Web + tags: + - orchestrator + - error-tracking + - javascript_web + docs_urls: + - https://posthog.com/docs/libraries/js.md + - https://posthog.com/docs/references/posthog-js.md + - id: ruby + display_name: Ruby + tags: + - orchestrator + - error-tracking + - ruby + docs_urls: + - https://posthog.com/docs/libraries/ruby.md + - id: elixir + display_name: Elixir + tags: + - orchestrator + - error-tracking + - elixir + - phoenix + - plug + docs_urls: + - https://posthog.com/docs/libraries/elixir.md + - id: go + display_name: Go + tags: + - orchestrator + - error-tracking + - go + docs_urls: + - https://posthog.com/docs/libraries/go.md + - id: swift + display_name: Swift (iOS/macOS) + tags: + - orchestrator + - error-tracking + - swift + - ios + - macos + - swiftui + docs_urls: + - https://posthog.com/docs/libraries/ios.md + - https://posthog.com/docs/libraries/ios/usage.md + - https://posthog.com/docs/libraries/ios/configuration.md + - id: flutter + display_name: Flutter + tags: + - orchestrator + - error-tracking + - flutter + - dart + - mobile + docs_urls: + - https://posthog.com/docs/libraries/flutter.md + - id: react-native + display_name: React Native + tags: + - orchestrator + - error-tracking + - react-native + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/react-native.md + - id: expo + display_name: Expo + tags: + - orchestrator + - error-tracking + - expo + - react-native + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/react-native.md + - id: astro-static + display_name: Astro (Static) + tags: + - orchestrator + - error-tracking + - astro + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: astro-view-transitions + display_name: Astro (View Transitions) + tags: + - orchestrator + - error-tracking + - astro + - astro-view-transitions + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: astro-ssr + display_name: Astro (SSR) + tags: + - orchestrator + - error-tracking + - astro + - astro-ssr + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: astro-hybrid + display_name: Astro (Hybrid) + tags: + - orchestrator + - error-tracking + - astro + - astro-hybrid + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: angular + display_name: Angular + tags: + - orchestrator + - error-tracking + - angular + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/angular.md diff --git a/context/skills/basic-integration/error-tracking-step/description.md b/context/skills/basic-integration/error-tracking-step/description.md new file mode 100644 index 00000000..352bbea7 --- /dev/null +++ b/context/skills/basic-integration/error-tracking-step/description.md @@ -0,0 +1,17 @@ +# Add error tracking + +Set up the framework's GLOBAL error boundary so uncaught errors and exceptions +reach PostHog — one handler, not hand-wrapped across files. + +Follow the framework's own mechanism for a global error handler, using the +reference example and the docs for the exact pattern. Find the init or app entry, +add the handler there. Do not read through the whole app or wrap individual +components or routes by hand. + +If the app already has natural exception boundaries — a server-side API error +handler, a critical flow with its own try/catch — capturing there too is worth a +single edit. The global handler is the floor, not the only place errors matter. + +## Reference + +{references} diff --git a/context/skills/basic-integration/identify/config.yaml b/context/skills/basic-integration/identify/config.yaml new file mode 100644 index 00000000..f257eeb4 --- /dev/null +++ b/context/skills/basic-integration/identify/config.yaml @@ -0,0 +1,11 @@ +type: docs-only +template: description.md +description: Identify users at login and signup +tags: [orchestrator, identify] +variants: + - id: all + display_name: PostHog identify step + tags: [orchestrator, identify] + docs_urls: + - https://posthog.com/docs/getting-started/identify-users.md + - https://posthog.com/docs/product-analytics/identity-resolution.md diff --git a/context/skills/basic-integration/identify/description.md b/context/skills/basic-integration/identify/description.md new file mode 100644 index 00000000..c5a002bc --- /dev/null +++ b/context/skills/basic-integration/identify/description.md @@ -0,0 +1,22 @@ +# Identify users + +Call the SDK's identify method at the moment the app learns who the user is — +typically on login and signup success. + +- Use a stable unique id as the distinct id (the user id from your auth), not an + email or display name. +- Attach useful person properties (email, name, plan). +- Reset the session on logout, where the SDK supports it, so the next user starts + clean. + +Find the auth flow first: login and signup handlers, session callbacks. If the +app has no concept of a user, there is nothing to identify — report that and stop. + +If the app has both a client and a server, keep them on the same person: forward +the client's distinct id and session id to the backend (the +`X-POSTHOG-DISTINCT-ID` and `X-POSTHOG-SESSION-ID` request headers are the usual +carrier) so server-side events stitch to the same user rather than splitting off. + +## Reference + +{references} diff --git a/context/skills/basic-integration/init/config.yaml b/context/skills/basic-integration/init/config.yaml new file mode 100644 index 00000000..f8683f88 --- /dev/null +++ b/context/skills/basic-integration/init/config.yaml @@ -0,0 +1,381 @@ +type: docs-only +template: description.md +description: Initialize PostHog and set its environment variables +tags: + - orchestrator + - init +variants: + - id: nextjs-app-router + display_name: Next.js App Router + tags: + - orchestrator + - init + - nextjs + - react + - ssr + - app-router + - javascript + docs_urls: + - https://posthog.com/docs/libraries/next-js.md + - id: nextjs-pages-router + display_name: Next.js Pages Router + tags: + - orchestrator + - init + - nextjs + - react + - ssr + - pages-router + - javascript + docs_urls: + - https://posthog.com/docs/libraries/next-js.md + - id: react-react-router-6 + display_name: React Router v6 + tags: + - orchestrator + - init + - react + - react-router + - v6 + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v6.md + - id: react-react-router-7-framework + display_name: React Router v7 - Framework mode + tags: + - orchestrator + - init + - react + - react-router + - v7 + - framework + - ssr + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v7-framework-mode.md + - id: react-react-router-7-data + display_name: React Router v7 - Data mode + tags: + - orchestrator + - init + - react + - react-router + - v7 + - data + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v7-data-mode.md + - id: react-react-router-7-declarative + display_name: React Router v7 - Declarative mode + tags: + - orchestrator + - init + - react + - react-router + - v7 + - declarative + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v7-declarative-mode.md + - id: react-vite + display_name: React (Vite) + tags: + - orchestrator + - init + - react + - vite + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react.md + - id: nuxt-3-6 + display_name: Nuxt 3.6 + tags: + - orchestrator + - init + - nuxt + - javascript + docs_urls: + - https://posthog.com/docs/libraries/nuxt-js-3-6.md + - id: nuxt-4 + display_name: Nuxt 4 + tags: + - orchestrator + - init + - nuxt + - vue + - ssr + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/nuxt-js.md + - id: vue-3 + display_name: Vue 3 + tags: + - orchestrator + - init + - vue + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/vue-js.md + - id: django + display_name: Django + tags: + - orchestrator + - init + - django + - python + docs_urls: + - https://posthog.com/docs/libraries/django.md + - id: flask + display_name: Flask + tags: + - orchestrator + - init + - flask + - python + docs_urls: + - https://posthog.com/docs/libraries/flask.md + - id: fastapi + display_name: FastAPI + tags: + - orchestrator + - init + - fastapi + - python + docs_urls: + - https://posthog.com/docs/libraries/python.md + - id: react-tanstack-router-file-based + display_name: React with TanStack Router (file-based) + tags: + - orchestrator + - init + - react + - tanstack-router + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/tanstack-start.md + - id: react-tanstack-router-code-based + display_name: React with TanStack Router (code-based) + tags: + - orchestrator + - init + - react + - tanstack-router + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/tanstack-start.md + - id: tanstack-start + display_name: TanStack Start + tags: + - orchestrator + - init + - react + - tanstack-start + - tanstack-router + - javascript + docs_urls: + - https://posthog.com/docs/libraries/tanstack-start.md + - id: laravel + display_name: Laravel + tags: + - orchestrator + - init + - laravel + - php + docs_urls: + - https://posthog.com/docs/libraries/laravel.md + - id: php + display_name: PHP + tags: + - orchestrator + - init + - php + docs_urls: + - https://posthog.com/docs/libraries/php.md + - id: ruby-on-rails + display_name: Ruby on Rails + tags: + - orchestrator + - init + - ruby-on-rails + - ruby + docs_urls: + - https://posthog.com/docs/libraries/ruby-on-rails.md + - https://posthog.com/docs/libraries/ruby.md + - id: android + display_name: Android + tags: + - orchestrator + - init + - android + - java + - kotlin + docs_urls: + - https://posthog.com/docs/libraries/android.md + - id: sveltekit + display_name: SvelteKit + tags: + - orchestrator + - init + - sveltekit + - svelte + - javascript + docs_urls: + - https://posthog.com/docs/libraries/svelte.md + - id: python + display_name: Python + tags: + - orchestrator + - init + - python + docs_urls: + - https://posthog.com/docs/libraries/python.md + - https://posthog.com/docs/references/posthog-python.md + - id: javascript_node + display_name: JavaScript Node + tags: + - orchestrator + - init + - javascript_node + docs_urls: + - https://posthog.com/docs/libraries/node.md + - https://posthog.com/docs/references/posthog-node.md + - id: javascript_web + display_name: JavaScript Web + tags: + - orchestrator + - init + - javascript_web + docs_urls: + - https://posthog.com/docs/libraries/js.md + - https://posthog.com/docs/references/posthog-js.md + - id: ruby + display_name: Ruby + tags: + - orchestrator + - init + - ruby + docs_urls: + - https://posthog.com/docs/libraries/ruby.md + - id: elixir + display_name: Elixir + tags: + - orchestrator + - init + - elixir + - phoenix + - plug + docs_urls: + - https://posthog.com/docs/libraries/elixir.md + - id: go + display_name: Go + tags: + - orchestrator + - init + - go + docs_urls: + - https://posthog.com/docs/libraries/go.md + - id: swift + display_name: Swift (iOS/macOS) + tags: + - orchestrator + - init + - swift + - ios + - macos + - swiftui + docs_urls: + - https://posthog.com/docs/libraries/ios.md + - https://posthog.com/docs/libraries/ios/usage.md + - https://posthog.com/docs/libraries/ios/configuration.md + - id: flutter + display_name: Flutter + tags: + - orchestrator + - init + - flutter + - dart + - mobile + docs_urls: + - https://posthog.com/docs/libraries/flutter.md + - id: react-native + display_name: React Native + tags: + - orchestrator + - init + - react-native + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/react-native.md + - id: expo + display_name: Expo + tags: + - orchestrator + - init + - expo + - react-native + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/react-native.md + - id: astro-static + display_name: Astro (Static) + tags: + - orchestrator + - init + - astro + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: astro-view-transitions + display_name: Astro (View Transitions) + tags: + - orchestrator + - init + - astro + - astro-view-transitions + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: astro-ssr + display_name: Astro (SSR) + tags: + - orchestrator + - init + - astro + - astro-ssr + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: astro-hybrid + display_name: Astro (Hybrid) + tags: + - orchestrator + - init + - astro + - astro-hybrid + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: angular + display_name: Angular + tags: + - orchestrator + - init + - angular + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/angular.md diff --git a/context/skills/basic-integration/init/description.md b/context/skills/basic-integration/init/description.md new file mode 100644 index 00000000..2440423e --- /dev/null +++ b/context/skills/basic-integration/init/description.md @@ -0,0 +1,22 @@ +# Initialize PostHog + +Set up PostHog so the SDK is configured once and available across the app. + +## Environment variables + +Set the PostHog keys through the wizard tools (`set_env_values`), never hardcoded. +Use the framework's public env-var convention so the client can read them. + +- the public project token +- the PostHog host + +## Init point + +Create the framework's single initialization point that runs once on the client, +following the reference example and the docs for the right pattern. Read the +existing provider or entry file before editing, and add PostHog alongside what is +already there rather than replacing it. + +## Reference + +{references} diff --git a/context/skills/basic-integration/install/config.yaml b/context/skills/basic-integration/install/config.yaml new file mode 100644 index 00000000..34c5a473 --- /dev/null +++ b/context/skills/basic-integration/install/config.yaml @@ -0,0 +1,381 @@ +type: docs-only +template: description.md +description: Install the PostHog SDK with the project's package manager +tags: + - orchestrator + - install +variants: + - id: nextjs-app-router + display_name: Next.js App Router + tags: + - orchestrator + - install + - nextjs + - react + - ssr + - app-router + - javascript + docs_urls: + - https://posthog.com/docs/libraries/next-js.md + - id: nextjs-pages-router + display_name: Next.js Pages Router + tags: + - orchestrator + - install + - nextjs + - react + - ssr + - pages-router + - javascript + docs_urls: + - https://posthog.com/docs/libraries/next-js.md + - id: react-react-router-6 + display_name: React Router v6 + tags: + - orchestrator + - install + - react + - react-router + - v6 + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v6.md + - id: react-react-router-7-framework + display_name: React Router v7 - Framework mode + tags: + - orchestrator + - install + - react + - react-router + - v7 + - framework + - ssr + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v7-framework-mode.md + - id: react-react-router-7-data + display_name: React Router v7 - Data mode + tags: + - orchestrator + - install + - react + - react-router + - v7 + - data + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v7-data-mode.md + - id: react-react-router-7-declarative + display_name: React Router v7 - Declarative mode + tags: + - orchestrator + - install + - react + - react-router + - v7 + - declarative + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react-router/react-router-v7-declarative-mode.md + - id: react-vite + display_name: React (Vite) + tags: + - orchestrator + - install + - react + - vite + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/react.md + - id: nuxt-3-6 + display_name: Nuxt 3.6 + tags: + - orchestrator + - install + - nuxt + - javascript + docs_urls: + - https://posthog.com/docs/libraries/nuxt-js-3-6.md + - id: nuxt-4 + display_name: Nuxt 4 + tags: + - orchestrator + - install + - nuxt + - vue + - ssr + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/nuxt-js.md + - id: vue-3 + display_name: Vue 3 + tags: + - orchestrator + - install + - vue + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/vue-js.md + - id: django + display_name: Django + tags: + - orchestrator + - install + - django + - python + docs_urls: + - https://posthog.com/docs/libraries/django.md + - id: flask + display_name: Flask + tags: + - orchestrator + - install + - flask + - python + docs_urls: + - https://posthog.com/docs/libraries/flask.md + - id: fastapi + display_name: FastAPI + tags: + - orchestrator + - install + - fastapi + - python + docs_urls: + - https://posthog.com/docs/libraries/python.md + - id: react-tanstack-router-file-based + display_name: React with TanStack Router (file-based) + tags: + - orchestrator + - install + - react + - tanstack-router + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/tanstack-start.md + - id: react-tanstack-router-code-based + display_name: React with TanStack Router (code-based) + tags: + - orchestrator + - install + - react + - tanstack-router + - spa + - javascript + docs_urls: + - https://posthog.com/docs/libraries/tanstack-start.md + - id: tanstack-start + display_name: TanStack Start + tags: + - orchestrator + - install + - react + - tanstack-start + - tanstack-router + - javascript + docs_urls: + - https://posthog.com/docs/libraries/tanstack-start.md + - id: laravel + display_name: Laravel + tags: + - orchestrator + - install + - laravel + - php + docs_urls: + - https://posthog.com/docs/libraries/laravel.md + - id: php + display_name: PHP + tags: + - orchestrator + - install + - php + docs_urls: + - https://posthog.com/docs/libraries/php.md + - id: ruby-on-rails + display_name: Ruby on Rails + tags: + - orchestrator + - install + - ruby-on-rails + - ruby + docs_urls: + - https://posthog.com/docs/libraries/ruby-on-rails.md + - https://posthog.com/docs/libraries/ruby.md + - id: android + display_name: Android + tags: + - orchestrator + - install + - android + - java + - kotlin + docs_urls: + - https://posthog.com/docs/libraries/android.md + - id: sveltekit + display_name: SvelteKit + tags: + - orchestrator + - install + - sveltekit + - svelte + - javascript + docs_urls: + - https://posthog.com/docs/libraries/svelte.md + - id: python + display_name: Python + tags: + - orchestrator + - install + - python + docs_urls: + - https://posthog.com/docs/libraries/python.md + - https://posthog.com/docs/references/posthog-python.md + - id: javascript_node + display_name: JavaScript Node + tags: + - orchestrator + - install + - javascript_node + docs_urls: + - https://posthog.com/docs/libraries/node.md + - https://posthog.com/docs/references/posthog-node.md + - id: javascript_web + display_name: JavaScript Web + tags: + - orchestrator + - install + - javascript_web + docs_urls: + - https://posthog.com/docs/libraries/js.md + - https://posthog.com/docs/references/posthog-js.md + - id: ruby + display_name: Ruby + tags: + - orchestrator + - install + - ruby + docs_urls: + - https://posthog.com/docs/libraries/ruby.md + - id: elixir + display_name: Elixir + tags: + - orchestrator + - install + - elixir + - phoenix + - plug + docs_urls: + - https://posthog.com/docs/libraries/elixir.md + - id: go + display_name: Go + tags: + - orchestrator + - install + - go + docs_urls: + - https://posthog.com/docs/libraries/go.md + - id: swift + display_name: Swift (iOS/macOS) + tags: + - orchestrator + - install + - swift + - ios + - macos + - swiftui + docs_urls: + - https://posthog.com/docs/libraries/ios.md + - https://posthog.com/docs/libraries/ios/usage.md + - https://posthog.com/docs/libraries/ios/configuration.md + - id: flutter + display_name: Flutter + tags: + - orchestrator + - install + - flutter + - dart + - mobile + docs_urls: + - https://posthog.com/docs/libraries/flutter.md + - id: react-native + display_name: React Native + tags: + - orchestrator + - install + - react-native + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/react-native.md + - id: expo + display_name: Expo + tags: + - orchestrator + - install + - expo + - react-native + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/react-native.md + - id: astro-static + display_name: Astro (Static) + tags: + - orchestrator + - install + - astro + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: astro-view-transitions + display_name: Astro (View Transitions) + tags: + - orchestrator + - install + - astro + - astro-view-transitions + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: astro-ssr + display_name: Astro (SSR) + tags: + - orchestrator + - install + - astro + - astro-ssr + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: astro-hybrid + display_name: Astro (Hybrid) + tags: + - orchestrator + - install + - astro + - astro-hybrid + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/astro.md + - id: angular + display_name: Angular + tags: + - orchestrator + - install + - angular + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/angular.md diff --git a/context/skills/basic-integration/install/description.md b/context/skills/basic-integration/install/description.md new file mode 100644 index 00000000..f914b263 --- /dev/null +++ b/context/skills/basic-integration/install/description.md @@ -0,0 +1,18 @@ +# Add the PostHog SDK to the manifest + +Declare PostHog in the project's package manifest directly. Do not run the package +manager, and do not build — the build task installs and verifies at the end. +Adding it to the manifest now keeps this step fast and batches the real install +into one place. + +Add the PostHog library appropriate for the app — the client library, plus the +server library if the app has server-side code that should send events. Use the +docs and the reference example to pick the right package and a current version +range, and match the style of the dependencies already in the manifest. + +Read the manifest first. If the dependency is already declared, leave it as is and +say so. Edit only the manifest — no lockfile, no install command. + +## Reference + +{references} diff --git a/context/skills/basic-integration/report/config.yaml b/context/skills/basic-integration/report/config.yaml new file mode 100644 index 00000000..1c454835 --- /dev/null +++ b/context/skills/basic-integration/report/config.yaml @@ -0,0 +1,9 @@ +type: docs-only +template: description.md +description: Write the PostHog setup report from the run's handoffs +tags: [orchestrator, report] +variants: + - id: all + display_name: PostHog report step + tags: [orchestrator, report] + docs_urls: [] diff --git a/context/skills/basic-integration/report/description.md b/context/skills/basic-integration/report/description.md new file mode 100644 index 00000000..186303d7 --- /dev/null +++ b/context/skills/basic-integration/report/description.md @@ -0,0 +1,33 @@ +# Write the setup report + +Write `posthog-setup-report.md` at the project root summarizing the integration. +Draw on two sources only: + +- the run's queue log — `.posthog-wizard-cache/queue.json`, which holds each + task's handoff inline — for what each step did, whether identify was wired + or skipped, and any build conflict; +- `.posthog-wizard-cache/.posthog-events.json` — the events that were instrumented. + +Include: + +- A one-line summary of what was set up. +- What was installed and how PostHog was initialized. +- The events instrumented, as a table: event name, what it measures, and the file + (from `.posthog-wizard-cache/.posthog-events.json`). +- Whether user identification was wired or skipped, and why. +- The error tracking added. +- The dashboard link. +- Any build conflict, in full. +- Clear next steps for the user. + +End with a short "Before you merge" checklist, including only the items that +apply to what was set up: + +- If the app ships minified browser bundles, source maps must be uploaded so + error stack traces are readable — call it out with the docs link. +- The new env vars (the project token and host) are documented for other + developers and set in the deploy environments, not just locally. +- Returning users are identified on load, not only at the login moment, so a + returning user's events do not fragment across anonymous and identified. + +Keep it skimmable. This is the artifact the user opens after the run. diff --git a/scripts/build.js b/scripts/build.js index 28809b68..e8a4f7aa 100755 --- a/scripts/build.js +++ b/scripts/build.js @@ -12,6 +12,7 @@ import fs from 'fs'; import path from 'path'; import { generateAllSkills, fetchDoc } from './lib/skill-generator.js'; +import { buildAgents } from './lib/agent-generator.js'; import { generateMarketplace } from './lib/marketplace-generator.js'; import { loadDocsConfig, @@ -103,6 +104,15 @@ async function main() { const skillMenu = JSON.parse(fs.readFileSync(path.join(skillsDir, 'skill-menu.json'), 'utf8')); console.log(` ✓ skill-menu.json (${Object.keys(skillMenu.categories).length} categories, ${skills.length} skills)`); + console.log('\nBuilding agent prompts...'); + const agentsResult = buildAgents({ + configDir, + distDir, + baseUrl: process.env.AGENTS_BASE_URL, + version: BUILD_VERSION, + }); + console.log(` ✓ ${agentsResult.count} agent prompt(s) → dist/agents/ + agent-menu.json`); + const releaseAssetDocs = docEntries.filter(d => d.release_asset); if (releaseAssetDocs.length > 0) { console.log('\nWriting release-asset docs...'); diff --git a/scripts/dev-server.js b/scripts/dev-server.js index ee99c60d..3d000740 100644 --- a/scripts/dev-server.js +++ b/scripts/dev-server.js @@ -30,6 +30,7 @@ import { spawn } from 'child_process'; import chokidar from 'chokidar'; import { loadAndExpandSkills } from './lib/skill-generator.js'; +import { buildAgents } from './lib/agent-generator.js'; import { partialRebuild, loadDocContentsFromManifest, @@ -50,13 +51,18 @@ const configDir = path.join(repoRoot, 'context'); const distDir = path.join(repoRoot, 'dist'); const skillsDir = path.join(distDir, 'skills'); const skillsSourceDir = path.join(configDir, 'skills'); +const agentsSourceDir = path.join(configDir, 'agents'); +const agentsDir = path.join(distDir, 'agents'); const exampleAppsDir = path.join(repoRoot, 'example-apps'); const localSkillsUrl = `http://localhost:${PORT}/skills`; +const localAgentsUrl = `http://localhost:${PORT}/agents`; -// `generateManifest` reads SKILLS_BASE_URL from process.env. Partial rebuilds -// run in this process, so set it here too — the subprocess inherits it. +// `generateManifest` reads SKILLS_BASE_URL from process.env, and the agent build +// reads AGENTS_BASE_URL. Partial rebuilds run in this process, so set both here — +// the build subprocess inherits them. process.env.SKILLS_BASE_URL = localSkillsUrl; +process.env.AGENTS_BASE_URL = localAgentsUrl; // --- state --- @@ -184,6 +190,25 @@ async function drainQueue() { // --- watcher --- function handleEvent(event, absPath) { + // Agent prompts are decoupled from the skill incremental machinery. A change + // under context/agents/ just re-copies them wholesale — cheap. + if (absPath.startsWith(agentsSourceDir)) { + try { + const { count } = buildAgents({ + configDir, + distDir, + baseUrl: localAgentsUrl, + version: BUILD_VERSION, + }); + console.log( + `📝 ${event}: ${path.relative(repoRoot, absPath)} → rebuilt ${count} agent prompt(s)`, + ); + } catch (err) { + console.error(`❌ Agent rebuild failed: ${err.message}`); + } + return; + } + const decision = routeChange({ event, absPath, @@ -209,7 +234,7 @@ function handleEvent(event, absPath) { function setupWatcher() { const sep = path.sep; - const watcher = chokidar.watch([skillsSourceDir, exampleAppsDir], { + const watcher = chokidar.watch([skillsSourceDir, agentsSourceDir, exampleAppsDir], { ignoreInitial: true, persistent: true, followSymlinks: false, @@ -221,6 +246,7 @@ function setupWatcher() { console.log('\n👀 Watching:'); console.log(` 📁 ${path.relative(repoRoot, skillsSourceDir)}`); + console.log(` 📁 ${path.relative(repoRoot, agentsSourceDir)}`); console.log(` 📁 ${path.relative(repoRoot, exampleAppsDir)}`); return watcher; @@ -268,6 +294,17 @@ function createServer() { return; } + const agentMatch = req.url?.match(/^\/agents\/([\w-]+\.md)$/); + if (agentMatch) { + serveFile(res, path.join(agentsDir, agentMatch[1]), 'text/markdown; charset=utf-8'); + return; + } + + if (req.url === '/agent-menu.json') { + serveFile(res, path.join(agentsDir, 'agent-menu.json'), 'application/json'); + return; + } + if (req.url === '/skills-mcp-resources.zip' || req.url === '/') { serveFile( res, @@ -279,7 +316,7 @@ function createServer() { } res.writeHead(404, { 'Content-Type': 'text/plain', ...NO_CACHE_HEADERS }); - res.end('Not found. Available endpoints:\n /skill-menu.json\n /skills-mcp-resources.zip\n /skills/{id}.zip'); + res.end('Not found. Available endpoints:\n /skill-menu.json\n /skills-mcp-resources.zip\n /skills/{id}.zip\n /agent-menu.json\n /agents/{type}.md'); }); server.listen(PORT, () => { @@ -287,6 +324,8 @@ function createServer() { console.log(`\n📍 Skills bundle: http://localhost:${PORT}/skills-mcp-resources.zip`); console.log(`📍 Individual skill: http://localhost:${PORT}/skills/{id}.zip`); console.log(`📋 Skills menu: http://localhost:${PORT}/skill-menu.json`); + console.log(`🤖 Agent prompt: http://localhost:${PORT}/agents/{type}.md`); + console.log(`📋 Agents menu: http://localhost:${PORT}/agent-menu.json`); }); return server; diff --git a/scripts/lib/agent-generator.js b/scripts/lib/agent-generator.js new file mode 100644 index 00000000..d787152d --- /dev/null +++ b/scripts/lib/agent-generator.js @@ -0,0 +1,69 @@ +/** + * Agent-prompt content type — the WHAT of the orchestrator runner. + * + * An agent prompt is one markdown file per task type. Its frontmatter carries + * the artifacts the executor configures the run with (model, skills, tools, + * dependsOn); its body is the instruction the task agent reads. Unlike skills, + * agent prompts are self-contained single files with no references/, so they are + * served as raw markdown rather than zipped. The wizard parses the frontmatter + * when it loads a task by type. + * + * Source: context/agents/.md + * Output: dist/agents/.md + dist/agents/agent-menu.json + */ + +import fs from 'fs'; +import path from 'path'; + +const DEFAULT_AGENTS_BASE_URL = + 'https://github.com/PostHog/context-mill/releases/latest/download/agents'; + +/** The agent ids available in source, derived from the `.md` filenames. */ +export function loadAgentIds(agentsSourceDir) { + if (!fs.existsSync(agentsSourceDir)) return []; + return fs + .readdirSync(agentsSourceDir) + // README.md is documentation for authors, not a served prompt. + .filter(f => f.endsWith('.md') && f !== 'README.md') + .map(f => f.slice(0, -'.md'.length)) + .sort(); +} + +/** + * Copy every agent-prompt markdown file into dist/agents/ and write the menu the + * wizard fetches to discover available types. The menu carries a full + * downloadUrl per agent so the dev-server and the release host can differ + * without the wizard composing URLs. Returns { count, agentsDistDir }. + */ +export function buildAgents({ configDir, distDir, baseUrl, version = 'dev' }) { + const agentsSourceDir = path.join(configDir, 'agents'); + const agentsDistDir = path.join(distDir, 'agents'); + const resolvedBase = (baseUrl || DEFAULT_AGENTS_BASE_URL).replace(/\/+$/, ''); + + fs.mkdirSync(agentsDistDir, { recursive: true }); + + const ids = loadAgentIds(agentsSourceDir); + const agents = []; + for (const id of ids) { + fs.copyFileSync( + path.join(agentsSourceDir, `${id}.md`), + path.join(agentsDistDir, `${id}.md`), + ); + agents.push({ id, downloadUrl: `${resolvedBase}/${id}.md` }); + } + + const menu = { version: '1.0', buildVersion: version, agents }; + fs.writeFileSync( + path.join(agentsDistDir, 'agent-menu.json'), + JSON.stringify(menu, null, 2) + '\n', + ); + + // Reconcile: drop dist files whose source markdown was removed. + const keep = new Set(ids.map(id => `${id}.md`)); + keep.add('agent-menu.json'); + for (const file of fs.readdirSync(agentsDistDir)) { + if (!keep.has(file)) fs.rmSync(path.join(agentsDistDir, file)); + } + + return { count: agents.length, agentsDistDir }; +} diff --git a/scripts/lib/skill-generator.js b/scripts/lib/skill-generator.js index c766669b..b07ae1ef 100644 --- a/scripts/lib/skill-generator.js +++ b/scripts/lib/skill-generator.js @@ -614,15 +614,30 @@ async function generateSkill({ await processDoc(docEntry); } + // Collect commandments for this skill's tags. + const rules = collectCommandments(skill.tags || [], commandmentsConfig); + const commandmentsText = formatCommandments(rules); + + // Also emit them as a reference file. The orchestrator installs this skill + // as the framework reference and points its task agents at individual + // files, so the rules must exist outside the SKILL.md body. + if (rules.length > 0) { + fs.writeFileSync( + path.join(referencesDir, 'COMMANDMENTS.md'), + `# Framework rules\n\nFollow these when integrating PostHog into this framework.\n\n${commandmentsText}\n`, + 'utf8', + ); + references.push({ + filename: 'COMMANDMENTS.md', + description: 'Framework-specific rules the integration must follow', + }); + } + // Build references list for SKILL.md const referencesText = references .map(ref => `- \`references/${ref.filename}\` - ${ref.description}`) .join('\n'); - // Collect commandments for this skill's tags - const rules = collectCommandments(skill.tags || [], commandmentsConfig); - const commandmentsText = formatCommandments(rules); - // Format workflow steps for skills that use the {workflow} placeholder const workflowText = formatWorkflowSteps(workflowSteps);