From 9ee4c163ef17b3fb770ebb85b1ee97127d6f4579 Mon Sep 17 00:00:00 2001 From: John W Date: Wed, 23 Sep 2026 13:22:25 -0700 Subject: [PATCH 1/2] feat(feature-flags): add the feature-flags step skill for the wizard Adds integration-v2/feature-flags-step, the docs-only skill the wizard's feature-flags evaluate task loads. One variant per integration framework, each pointing at that SDK's flag docs plus the shared flag pages, and the step-skill parity test now covers it. --- .../feature-flags-step/config.yaml | 451 ++++++++++++++++++ .../feature-flags-step/description.md | 19 + .../tests/error-tracking-step-parity.test.js | 25 +- 3 files changed, 483 insertions(+), 12 deletions(-) create mode 100644 context/skills/integration-v2/feature-flags-step/config.yaml create mode 100644 context/skills/integration-v2/feature-flags-step/description.md diff --git a/context/skills/integration-v2/feature-flags-step/config.yaml b/context/skills/integration-v2/feature-flags-step/config.yaml new file mode 100644 index 00000000..ab907eef --- /dev/null +++ b/context/skills/integration-v2/feature-flags-step/config.yaml @@ -0,0 +1,451 @@ +# Orchestrator step-skill: fetched by task agents, never surfaced as a command. +# The framework matrix mirrors the canonical integration group's ids, but the +# docs are flag pages: integration's docs_urls teach SDK install and would give +# the evaluate task nothing about evaluating once, flag-key constants, or +# reporting evaluations back. +type: docs-only +template: description.md +description: Evaluate the example PostHog feature flags, one per side of the app +tags: [orchestrator, feature-flags] +cli: + role: internal +shared_docs: +- https://posthog.com/docs/feature-flags/adding-feature-flag-code.md +- https://posthog.com/docs/feature-flags/best-practices.md +- https://posthog.com/docs/feature-flags/local-evaluation.md +variants: +- id: nextjs-app-router + framework: nextjs + default: true + display_name: Next.js App Router + tags: + - nextjs + - react + - ssr + - app-router + - javascript + - javascript_web + - javascript_node + docs_urls: + - https://posthog.com/docs/feature-flags/installation/react.md + - https://posthog.com/docs/libraries/next-js.md + - https://posthog.com/docs/feature-flags/installation/nodejs.md +- id: nextjs-pages-router + framework: nextjs + display_name: Next.js Pages Router + tags: + - nextjs + - react + - ssr + - pages-router + - javascript + - javascript_web + - javascript_node + docs_urls: + - https://posthog.com/docs/feature-flags/installation/react.md + - https://posthog.com/docs/libraries/next-js.md + - https://posthog.com/docs/feature-flags/installation/nodejs.md +- id: react-react-router-6 + framework: react-router + default: true + display_name: React Router v6 + tags: + - react + - react-router + - v6 + - spa + - javascript + - javascript_web + docs_urls: + - https://posthog.com/docs/feature-flags/installation/react.md +- id: react-react-router-7-framework + framework: react-router + display_name: React Router v7 - Framework mode + tags: + - react + - react-router + - v7 + - framework + - ssr + - javascript + - javascript_node + - javascript_web + docs_urls: + - https://posthog.com/docs/feature-flags/installation/react.md + - https://posthog.com/docs/feature-flags/installation/nodejs.md +- id: react-react-router-7-data + framework: react-router + display_name: React Router v7 - Data mode + tags: + - react + - react-router + - v7 + - data + - spa + - javascript + - javascript_web + docs_urls: + - https://posthog.com/docs/feature-flags/installation/react.md +- id: react-react-router-7-declarative + framework: react-router + display_name: React Router v7 - Declarative mode + tags: + - react + - react-router + - v7 + - declarative + - spa + - javascript + - javascript_web + docs_urls: + - https://posthog.com/docs/feature-flags/installation/react.md +- id: react-vite + display_name: React (Vite) + tags: + - react + - vite + - spa + - javascript + - javascript_web + docs_urls: + - https://posthog.com/docs/feature-flags/installation/react.md +- id: nuxt-3-6 + framework: nuxt + display_name: Nuxt 3.6 + tags: + - nuxt + - javascript + - javascript_web + - javascript_node + docs_urls: + - https://posthog.com/docs/feature-flags/installation/web.md + - https://posthog.com/docs/libraries/nuxt-js.md + - https://posthog.com/docs/feature-flags/installation/nodejs.md +- id: nuxt-4 + framework: nuxt + default: true + display_name: Nuxt 4 + tags: + - nuxt + - vue + - ssr + - javascript + - typescript + - javascript_web + - javascript_node + docs_urls: + - https://posthog.com/docs/feature-flags/installation/web.md + - https://posthog.com/docs/libraries/nuxt-js.md + - https://posthog.com/docs/feature-flags/installation/nodejs.md +- id: vue-3 + framework: vue + display_name: Vue 3 + tags: + - vue + - javascript + - typescript + - javascript_web + docs_urls: + - https://posthog.com/docs/feature-flags/installation/web.md + - https://posthog.com/docs/libraries/vue-js.md +- id: django + framework: django + display_name: Django + tags: + - django + - python + docs_urls: + - https://posthog.com/docs/feature-flags/installation/python.md + - https://posthog.com/docs/libraries/django.md + - https://posthog.com/docs/feature-flags/installation/web.md +- id: flask + framework: flask + display_name: Flask + tags: + - flask + - python + docs_urls: + - https://posthog.com/docs/feature-flags/installation/python.md + - https://posthog.com/docs/libraries/flask.md + - https://posthog.com/docs/feature-flags/installation/web.md +- id: fastapi + framework: fastapi + display_name: FastAPI + tags: + - fastapi + - python + docs_urls: + - https://posthog.com/docs/feature-flags/installation/python.md +- id: react-tanstack-router-file-based + framework: tanstack-router + display_name: React with TanStack Router (file-based) + tags: + - react + - tanstack-router + - spa + - javascript + - javascript_web + docs_urls: + - https://posthog.com/docs/feature-flags/installation/react.md + - https://posthog.com/docs/libraries/tanstack-start.md +- id: react-tanstack-router-code-based + framework: tanstack-router + default: true + display_name: React with TanStack Router (code-based) + tags: + - react + - tanstack-router + - spa + - javascript + - javascript_web + docs_urls: + - https://posthog.com/docs/feature-flags/installation/react.md + - https://posthog.com/docs/libraries/tanstack-start.md +- id: tanstack-start + framework: tanstack-start + display_name: TanStack Start + tags: + - react + - tanstack-start + - tanstack-router + - javascript + - javascript_web + - javascript_node + docs_urls: + - https://posthog.com/docs/feature-flags/installation/react.md + - https://posthog.com/docs/libraries/tanstack-start.md + - https://posthog.com/docs/feature-flags/installation/nodejs.md +- id: laravel + framework: laravel + display_name: Laravel + tags: + - laravel + - php + docs_urls: + - https://posthog.com/docs/feature-flags/installation/php.md + - https://posthog.com/docs/libraries/laravel.md + - https://posthog.com/docs/feature-flags/installation/web.md +- id: php + display_name: PHP + tags: + - php + docs_urls: + - https://posthog.com/docs/feature-flags/installation/php.md + - https://posthog.com/docs/feature-flags/installation/web.md +- id: wordpress + framework: wordpress + display_name: WordPress + tags: + - wordpress + - php + - cms + docs_urls: + - https://posthog.com/docs/feature-flags/installation/php.md + - https://posthog.com/docs/libraries/wordpress.md + - https://posthog.com/docs/feature-flags/installation/web.md +- id: ruby-on-rails + framework: rails + display_name: Ruby on Rails + tags: + - ruby-on-rails + - ruby + docs_urls: + - https://posthog.com/docs/feature-flags/installation/ruby.md + - https://posthog.com/docs/libraries/ruby-on-rails.md + - https://posthog.com/docs/feature-flags/installation/web.md +- id: android + framework: android + display_name: Android + tags: + - android + - java + - kotlin + docs_urls: + - https://posthog.com/docs/feature-flags/installation/android.md +- id: sveltekit + framework: sveltekit + display_name: SvelteKit + tags: + - sveltekit + - svelte + - javascript + - javascript_web + - javascript_node + docs_urls: + - https://posthog.com/docs/feature-flags/installation/web.md + - https://posthog.com/docs/libraries/svelte.md + - https://posthog.com/docs/feature-flags/installation/nodejs.md +- id: python + framework: python + display_name: Python + tags: + - python + docs_urls: + - https://posthog.com/docs/feature-flags/installation/python.md +- id: javascript_node + framework: javascript_node + display_name: JavaScript Node + tags: + - javascript_node + - javascript + docs_urls: + - https://posthog.com/docs/feature-flags/installation/nodejs.md +- id: javascript_web + framework: javascript_web + display_name: JavaScript Web + tags: + - javascript_web + - javascript + docs_urls: + - https://posthog.com/docs/feature-flags/installation/web.md +- id: ruby + framework: ruby + display_name: Ruby + tags: + - ruby + docs_urls: + - https://posthog.com/docs/feature-flags/installation/ruby.md +- id: elixir + framework: elixir + display_name: Elixir + tags: + - elixir + - phoenix + - plug + docs_urls: + - https://posthog.com/docs/libraries/elixir.md +- id: java + framework: java + display_name: Java (Spring Boot) + tags: + - java + - java-server + docs_urls: + - https://posthog.com/docs/libraries/java.md +- id: go + framework: go + display_name: Go + tags: + - go + docs_urls: + - https://posthog.com/docs/feature-flags/installation/go.md +- id: rust + framework: rust + display_name: Rust + tags: + - rust + docs_urls: + - https://posthog.com/docs/feature-flags/installation/rust.md +- id: swift + framework: swift + display_name: Swift (iOS/macOS) + tags: + - swift + - ios + - macos + - swiftui + - xcodegen + docs_urls: + - https://posthog.com/docs/feature-flags/installation/ios.md + - https://posthog.com/docs/libraries/ios/usage.md +- id: flutter + framework: flutter + display_name: Flutter + tags: + - flutter + - dart + - mobile + docs_urls: + - https://posthog.com/docs/feature-flags/installation/flutter.md +- id: kmp + display_name: Kotlin Multiplatform + tags: + - kmp + - kotlin + - multiplatform + - mobile + docs_urls: + - https://posthog.com/docs/feature-flags/installation/kmp.md +- id: react-native + framework: react-native + default: true + display_name: React Native + tags: + - react-native + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/feature-flags/installation/react-native.md +- id: expo + framework: react-native + display_name: Expo + tags: + - expo + - react-native + - javascript + - typescript + docs_urls: + - https://posthog.com/docs/libraries/react-native.md +- id: astro-static + framework: astro + display_name: Astro (Static) + tags: + - astro + - javascript + - typescript + - javascript_web + docs_urls: + - https://posthog.com/docs/feature-flags/installation/web.md + - https://posthog.com/docs/libraries/astro.md +- id: astro-view-transitions + framework: astro + display_name: Astro (View Transitions) + tags: + - astro + - astro-view-transitions + - javascript + - typescript + - javascript_web + docs_urls: + - https://posthog.com/docs/feature-flags/installation/web.md + - https://posthog.com/docs/libraries/astro.md +- id: astro-ssr + framework: astro + display_name: Astro (SSR) + tags: + - astro + - astro-ssr + - javascript + - typescript + - javascript_web + - javascript_node + docs_urls: + - https://posthog.com/docs/feature-flags/installation/web.md + - https://posthog.com/docs/libraries/astro.md + - https://posthog.com/docs/feature-flags/installation/nodejs.md +- id: astro-hybrid + framework: astro + default: true + display_name: Astro (Hybrid) + tags: + - astro + - astro-hybrid + - javascript + - typescript + - javascript_web + - javascript_node + docs_urls: + - https://posthog.com/docs/feature-flags/installation/web.md + - https://posthog.com/docs/libraries/astro.md + - https://posthog.com/docs/feature-flags/installation/nodejs.md +- id: angular + framework: angular + display_name: Angular + tags: + - angular + - javascript + - typescript + - javascript_web + docs_urls: + - https://posthog.com/docs/feature-flags/installation/web.md + - https://posthog.com/docs/libraries/angular.md diff --git a/context/skills/integration-v2/feature-flags-step/description.md b/context/skills/integration-v2/feature-flags-step/description.md new file mode 100644 index 00000000..1c3b0a99 --- /dev/null +++ b/context/skills/integration-v2/feature-flags-step/description.md @@ -0,0 +1,19 @@ +# Evaluate the example feature flags + +Add one evaluation for each example flag you were given, on that flag's own +side of the app, following the framework's flag docs and the best-practices +reference below. The backend flag is evaluated in server code with the server +SDK; the frontend flag in browser or device code with the client SDK. Never +evaluate a flag on the other side. + +On the backend, evaluate once per request and pass the result down; never +re-evaluate the same flag deeper in the call stack. Keep each flag key in a +constants module rather than as a string literal at the call site. Use the +identified user's distinct id for evaluation, the same id on both sides, and +report each evaluation back to PostHog the way the docs show for that SDK. + +Do not refactor unrelated code or add flags beyond the ones you were given. + +## Reference + +{references} diff --git a/scripts/lib/tests/error-tracking-step-parity.test.js b/scripts/lib/tests/error-tracking-step-parity.test.js index 8ec49a1b..9f539e17 100644 --- a/scripts/lib/tests/error-tracking-step-parity.test.js +++ b/scripts/lib/tests/error-tracking-step-parity.test.js @@ -5,17 +5,18 @@ import { loadSkillsConfig } from '../skill-generator.js'; const CONFIG_DIR = join(process.cwd(), 'context'); -// error-tracking-step declares its variants literally (its docs differ from -// integration's), but the orchestrator resolves it per framework with no +// Step skills declare their variants literally (their docs differ from +// integration's), but the orchestrator resolves them per framework with no // fallback. A variant added to integration and not copied here makes the -// default orchestrator flow abort for that framework. -describe('integration-v2/error-tracking-step', () => { - it('declares every integration variant, with the same framework', () => { - const config = loadSkillsConfig(CONFIG_DIR); - const keys = (group) => config[group].variants.map((v) => `${v.id}:${v.framework}`); +// orchestrator flow abort for that framework. +describe.each(['integration-v2/error-tracking-step', 'integration-v2/feature-flags-step'])( + '%s', + (stepSkillGroup) => { + it('declares every integration variant, with the same framework', () => { + const config = loadSkillsConfig(CONFIG_DIR); + const keys = (group) => config[group].variants.map((v) => `${v.id}:${v.framework}`); - expect(keys('integration-v2/error-tracking-step')).toEqual( - expect.arrayContaining(keys('integration')), - ); - }); -}); + expect(keys(stepSkillGroup)).toEqual(expect.arrayContaining(keys('integration'))); + }); + }, +); From 29f52b5bca73bfea4a07d262b7054f797496ac93 Mon Sep 17 00:00:00 2001 From: John W Date: Wed, 23 Sep 2026 14:14:36 -0700 Subject: [PATCH 2/2] refactor(feature-flags): keep the feature-flags step skill docs-only The wizard's evaluate prompt owns the instructions. The skill supplies only the posthog.com flag docs for each framework. --- .../feature-flags-step/description.md | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/context/skills/integration-v2/feature-flags-step/description.md b/context/skills/integration-v2/feature-flags-step/description.md index 1c3b0a99..c30e626e 100644 --- a/context/skills/integration-v2/feature-flags-step/description.md +++ b/context/skills/integration-v2/feature-flags-step/description.md @@ -1,18 +1,4 @@ -# Evaluate the example feature flags - -Add one evaluation for each example flag you were given, on that flag's own -side of the app, following the framework's flag docs and the best-practices -reference below. The backend flag is evaluated in server code with the server -SDK; the frontend flag in browser or device code with the client SDK. Never -evaluate a flag on the other side. - -On the backend, evaluate once per request and pass the result down; never -re-evaluate the same flag deeper in the call stack. Keep each flag key in a -constants module rather than as a string literal at the call site. Use the -identified user's distinct id for evaluation, the same id on both sides, and -report each evaluation back to PostHog the way the docs show for that SDK. - -Do not refactor unrelated code or add flags beyond the ones you were given. +# Evaluate PostHog feature flags ## Reference