Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 31 additions & 26 deletions .claude/skills/adding-framework-support/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ compatibility:
Designed for coding agents working on the PostHog wizard codebase.
metadata:
author: posthog
version: '2.0'
version: '2.1'
---

# Adding Framework Support
Expand All @@ -20,8 +20,9 @@ creating its own runner or changing existing routing defaults.

## Extend the framework configuration

Start with [FrameworkConfig](../../../src/programs/framework-config.ts) and a nearby
example under [src/programs/frameworks](../../../src/programs/frameworks/). Framework-specific
Start with [FrameworkConfig](../../../src/programs/framework-config.ts) and a
nearby example under
[src/programs/frameworks](../../../src/programs/frameworks/). Framework-specific
detection, context, environment conventions, and UI metadata belong here.
Integration instructions and examples belong in context-mill.

Expand All @@ -30,18 +31,23 @@ Integration instructions and examples belong in context-mill.
frameworks before language fallbacks and generic Node last; preserve the
overlap rules in the
[detection checks](../../../src/programs/detection/__tests__/framework.test.ts).
2. Add the config under `src/programs/frameworks/<name>/<name>-wizard-agent.ts`. Use a
`type` for framework context so it satisfies `Record<string, unknown>`.
2. Add the config under `src/programs/frameworks/<name>/<name>-wizard-agent.ts`.
Use a `type` for framework context so it satisfies `Record<string, unknown>`.
Export the config; the integration program already supplies execution.
3. Import the config into [FRAMEWORK_REGISTRY](../../../src/programs/frameworks/registry.ts).
The display label comes from `metadata.name`.
3. Import the config into
[FRAMEWORK_REGISTRY](../../../src/programs/frameworks/registry.ts).
`metadata.name` is the framework's label once detection or the picker settles
it.

Read the current interface for the complete required fields. In particular,
`detection.detectPackageManager` is required: reuse an adapter from
[package-manager detection](../../../src/programs/detection/package-manager.ts). Use
`metadata.setup.questions` for unresolved project variants; `gatherContext`
collects framework context. Optional notices and extra MCP servers also belong
in metadata.
[package-manager detection](../../../src/programs/detection/package-manager.ts).
Use `metadata.setup.questions` for unresolved project variants;
`metadata.gatherContext` collects framework context. When the gathered context
names a more specific variant, return its label from
`metadata.getDetectedFrameworkLabel(context)`; detection sets the label through
its context. Framework configs never use the UI. Optional notices and extra MCP
servers also belong in metadata.

Use `usesPackageJson: false` for frameworks without a package.json dependency.
Their required `getVersion` callback can return `undefined`. Minimum-version
Expand All @@ -52,17 +58,17 @@ itself.

## Detection and examples

| Starting point | Pattern to reuse |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [Next.js](../../../src/programs/frameworks/nextjs/) | `hasDeclaredDependency` from `utils/package-json`, `tryGetPackageJson` from `utils/setup-utils`, and router setup questions |
| [Django](../../../src/programs/frameworks/django/) | Python project files, context gathering, and Python package-manager detection |
| [Laravel](../../../src/programs/frameworks/laravel/) | Composer and framework-specific filesystem signals |
| [Rails](../../../src/programs/frameworks/rails/) | Gemfile detection and Ruby conventions |
| Starting point | Pattern to reuse |
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| [Next.js](../../../src/programs/frameworks/nextjs/) | `hasDeclaredDependency` from `utils/package-json`, `tryGetPackageJson` from `utils/package-json`, and router setup questions |
| [Django](../../../src/programs/frameworks/django/) | Python project files, context gathering, and Python package-manager detection |
| [Laravel](../../../src/programs/frameworks/laravel/) | Composer and framework-specific filesystem signals |
| [Rails](../../../src/programs/frameworks/rails/) | Gemfile detection and Ruby conventions |

Use [bounded filesystem helpers](../../../src/shared/utils/bounded-fs.ts) for project
scans and reads. They bound traversal and skip dependency/build directories; add
framework-specific exclusions with `extraIgnore`. Keep complex parsers and
detectors beside the config so they can be checked independently.
Use [bounded filesystem helpers](../../../src/shared/utils/bounded-fs.ts) for
project scans and reads. They bound traversal and skip dependency/build
directories; add framework-specific exclusions with `extraIgnore`. Keep complex
parsers and detectors beside the config so they can be checked independently.

## Complete the content side

Expand All @@ -84,15 +90,14 @@ enable a new gateway model.
Check detection against the target framework and the closest overlapping
framework/fallback. Reuse the existing detection checks; add a focused case only
for behavior they do not cover. Confirm package-manager selection and matching
content-mill variants. For an end-to-end run, use a disposable test app and the
context-mill variants. For an end-to-end run, use a disposable test app and the
[exploration guide](../exploring-the-wizard/SKILL.md).

For prompt, environment-upload, or outro changes, inspect the current
[integration program](../../../src/programs/posthog-integration/) and the
selected sequence. Some fields remain in the interface without a current
consumer: `getOutroNextSteps` is not used by the integration outro. Linear
post-run/outro hooks are not shared by the orchestrator; see the
[program guide](../adding-skill-program/SKILL.md).
selected sequence. `ui.getOutroNextSteps` and `analytics.getEventProperties`
have no consumer. Linear post-run/outro hooks are not shared by the
orchestrator; see the [program guide](../adding-skill-program/SKILL.md).

Use the proportionate validation guidance in
[wizard-development](../wizard-development/SKILL.md). Documentation-only changes
Expand Down
Loading
Loading