mcpbeat

Adding Framework Support

posthog/adding-framework-support

Add a new framework integration to the PostHog wizard. Use when adding support for a new language or framework (e.g. Ruby on Rails, Go, Angular). Covers creating the agent config, detection logic, registry entry, and enum/label additions.

2k tokens
context cost
the whole folder, loaded on every use
1
files
instructions only
0
copies elsewhere
how many repositories repackaged it
177
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/PostHog/wizard --skill adding-framework-support

The instruction itself

16 sections, as written by the author

Adding Framework Support

Architecture Overview

Every framework integration is a single FrameworkConfig object. The wizard has no switch statements or per-framework routing — everything is data-driven through:

  • FrameworkConfig (src/lib/framework-config.ts) — the interface each framework implements
  • FRAMEWORK_REGISTRY (src/lib/registry.ts) — maps Integration enum values to configs
  • Integration enum (src/lib/constants.ts) — enum order determines detection priority and menu display order

The universal runner (src/lib/agent-runner.ts) handles all shared behavior: debug logging, version checking, welcome message, beta notices, AI consent, credential flow, agent execution, error handling, and outro messaging.

Steps to Add a New Framework

1. Add to the Integration enum and labels

In src/lib/constants.ts, add the new value to Integration. Enum order matters — it controls both the detection priority (first match wins) and the display order in the CLI select menu. The display label comes from metadata.name in your FrameworkConfig.

export enum Integration {
  // ... existing entries
  rails = 'rails',  // insert at the desired detection/display position
}

2. Create the agent config file

Create src/<framework>/<framework>-wizard-agent.ts. This file exports:

  • A context type for framework-specific data
  • A FrameworkConfig<TContext> object (the full integration definition)
  • A thin runner function that just calls runAgentWizard(CONFIG, options)

Define a context type for any data gathered before the agent runs, then pass it as the generic parameter. Use type (not interface) so it satisfies the Record<string, unknown> constraint:

type RailsContext = {
  projectType?: RailsProjectType;
  gemfilePath?: string;
};

export const RAILS_AGENT_CONFIG: FrameworkConfig<RailsContext> = {
  // All context-consuming callbacks (getTags, getOutroChanges, etc.)
  // are now fully typed — no `any` casts needed.
};

Use an existing config as a template. The config has these sections:

metadata
  • name — display name (e.g. "Ruby on Rails")
  • integration — the enum value
  • docsUrl — PostHog docs URL for manual setup fallback
  • unsupportedVersionDocsUrl — optional fallback for old versions
  • beta — set true to show a [BETA] notice before running
  • gatherContext — optional async function to detect project-specific context (e.g. router type, project variant)
detection
  • packageName — the package to check (e.g. 'rails')
  • packageDisplayName — human-readable name for error messages
  • usesPackageJson — set false for non-JS frameworks (Python, PHP, Ruby, etc.)
  • getVersion — extract version from package.json (return undefined if usesPackageJson: false)
  • getVersionBucket — optional function to bucket versions for analytics (e.g. '7.x')
  • minimumVersion — optional minimum version string; runner auto-checks and bails if too old
  • getInstalledVersion — async function to get the installed version
  • detect — async function that returns true if this framework is present in the project
environment
  • uploadToHosting — whether to offer uploading env vars to hosting providers
  • getEnvVars — returns the env var names and values for this framework
analytics
  • getTags — returns analytics tags from gathered context
prompts
  • projectTypeDetection — text describing how to confirm the project type
  • packageInstallation — text describing package manager conventions
  • getAdditionalContextLines — optional function returning extra prompt lines from context
ui
  • successMessage, estimatedDurationMinutes
  • getOutroChanges — returns "what the agent did" bullets
  • getOutroNextSteps — returns "next steps" bullets

3. Register in the framework registry

In src/lib/registry.ts, import the config and add it:

import { NEW_AGENT_CONFIG } from '../<framework>/<framework>-wizard-agent';

export const FRAMEWORK_REGISTRY: Record<Integration, FrameworkConfig> = {
  // ... existing entries
  [Integration.newFramework]: NEW_AGENT_CONFIG,
};

4. Create framework utilities (if needed)

If the framework needs project type detection, version extraction, or other complex logic, create src/<framework>/utils.ts with the relevant functions. Keep this separate from the agent config to maintain testability.

Detection Guidelines

  • For JS/TS frameworks: check package.json for the framework package using hasPackageInstalled and tryGetPackageJson from src/utils/clack-utils.ts and src/utils/package-json.ts
  • For Python frameworks: glob for requirements*.txt, pyproject.toml, setup.py, Pipfile and check contents
  • For PHP frameworks: check composer.json or framework-specific files (e.g. artisan for Laravel)
  • For Ruby frameworks: check Gemfile or Gemfile.lock for the framework gem
  • Always ignore virtual environment and dependency directories in globs

Verification

After adding a framework:

pnpm build    # Must compile with no errors
pnpm test     # All tests must pass
pnpm fix      # No new lint errors (warnings are OK)

Reference Configs

Good examples to study:

  • JS framework: src/nextjs/nextjs-wizard-agent.ts — package.json detection, context gathering (router type)
  • Python framework: src/django/django-wizard-agent.ts — filesystem detection, usesPackageJson: false
  • PHP framework: src/laravel/laravel-wizard-agent.ts — composer.json detection, multiple detection strategies

How to use it

Copy the folder

Take posthog/adding-framework-support from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.