Skip to content

feat: posthog plugin service#918

Draft
skoob13 wants to merge 3 commits intomainfrom
feat/posthog-plugins
Draft

feat: posthog plugin service#918
skoob13 wants to merge 3 commits intomainfrom
feat/posthog-plugins

Conversation

@skoob13
Copy link
Contributor

@skoob13 skoob13 commented Feb 13, 2026

Need to ship the skills first before merging the PR.

TLDR:

This PR ships the embedded plugin for Claude Code and skills sync to Codex (as Codex doesn't have a plugin system yet). Skills are automatically pulled from posthog/posthog. The next step might be to reuse the same service for Wizard.

Also a few important changes:

  • The MCP is pinned to version 2–it ships the new PostHog data discovery through a unified HogQL interface.
  • Sets Claude Code's feature flag to offload all MCP tools to a virtual CLI, enabling progressive discovery. It works very well with skills.

Problem

Twig agents (Claude Code, Codex) need access to PostHog-specific skills, but currently there's no mechanism to deliver or update these skills. We need a plugin system that:

  1. Ships a baseline set of skills with the app
  2. Keeps skills up-to-date without requiring app releases
  3. Supports local skill development for contributors
  4. Works across both Claude Code (via plugins) and Codex (via ~/.agents/skills/)

Changes

New PostHog plugin system (plugins/posthog/) — a directory-based plugin format with plugin.json, MCP/LSP configs, and skill directories. Skills are markdown files (SKILL.md) that get passed to agents as context.

Three-tier skill sourcing with priority layering:

Source Location Priority
Shipped plugins/posthog/skills/ (committed) Lowest
Remote Downloaded from GitHub releases (skills.zip) Middle
Local dev plugins/posthog/local-skills/ (gitignored) Highest (dev only)

PosthogPluginService (apps/twig/src/main/services/posthog-plugin/service.ts) — injectable singleton that manages the full plugin lifecycle at runtime:

  • On startup: copies bundled plugin to userData, overlays any cached remote skills, syncs to Codex directory, starts a 30-minute update timer
  • On update: downloads skills.zip, extracts with atomic swap (.new/.old dirs to avoid partial states), re-assembles the runtime plugin, re-syncs to Codex
  • Includes throttling, reentrance guards, and graceful error handling (download failures are non-fatal — existing skills are preserved)

Build-time Vite plugin (copyPosthogPlugin in vite.main.config.mts) — at bundle time, copies the plugin directory to the build output, downloads and overlays remote skills, and in dev mode overlays local-skills/ on top. Watches all three sources for hot-reload.

Agent integration (AgentService) — injects PosthogPluginService and passes getPluginPath() to Claude Code sessions via the plugins option. Also adds x-posthog-mcp-version: 2 header to the PostHog MCP server config, and sets ENABLE_EXPERIMENTAL_MCP_CLI env var.

Dev toolingpnpm skills:pull script (scripts/pull-skills.mjs) downloads remote skills into local-skills/ for local editing and iteration.

Packaging — updated Forge config to unpack plugins/posthog/** from ASAR so the plugin directory is accessible at runtime.

Tests

Manual testing & service unit tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant