From caf360a6ae422ea4899518370743e10e4b11ff7b Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 9 Jun 2026 16:17:51 -0400 Subject: [PATCH 01/38] feat(agents): add `agents` content type, built and served alongside skills New content type for orchestrator agent prompts (the WHAT), parallel to skills. Source under transformation-config/agents/, built to dist/agents/ as raw markdown plus agent-menu.json, served by the dev server at /agents/.md and /agent-menu.json. Co-Authored-By: Claude Opus 4.8 (1M context) --- scripts/build.js | 10 +++++ scripts/dev-server.js | 47 +++++++++++++++++++++-- scripts/lib/agent-generator.js | 68 ++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 scripts/lib/agent-generator.js diff --git a/scripts/build.js b/scripts/build.js index deaf6da0..13411917 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, @@ -105,6 +106,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 8c1754cb..c9ae6ca6 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, @@ -51,13 +52,18 @@ const distDir = path.join(repoRoot, 'dist'); const skillsDir = path.join(distDir, 'skills'); const promptsDir = path.join(repoRoot, 'llm-prompts'); const skillsSourceDir = path.join(configDir, 'skills'); +const agentsSourceDir = path.join(configDir, 'agents'); +const agentsDir = path.join(distDir, 'agents'); const basicsDir = path.join(repoRoot, 'basics'); 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 --- @@ -186,6 +192,25 @@ async function drainQueue() { // --- watcher --- function handleEvent(event, absPath) { + // Agent prompts are decoupled from the skill incremental machinery. A change + // under transformation-config/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, @@ -211,7 +236,7 @@ function handleEvent(event, absPath) { function setupWatcher() { const sep = path.sep; - const watcher = chokidar.watch([skillsSourceDir, basicsDir], { + const watcher = chokidar.watch([skillsSourceDir, agentsSourceDir, basicsDir], { ignoreInitial: true, persistent: true, followSymlinks: false, @@ -223,6 +248,7 @@ function setupWatcher() { console.log('\n👀 Watching:'); console.log(` 📁 ${path.relative(repoRoot, skillsSourceDir)}`); + console.log(` 📁 ${path.relative(repoRoot, agentsSourceDir)}`); console.log(` 📁 ${path.relative(repoRoot, basicsDir)}`); return watcher; @@ -270,6 +296,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, @@ -281,7 +318,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, () => { @@ -289,6 +326,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..f84b912c --- /dev/null +++ b/scripts/lib/agent-generator.js @@ -0,0 +1,68 @@ +/** + * 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: transformation-config/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) + .filter(f => f.endsWith('.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 }; +} From e70da8b14fa825a95fd5a31fd2f43137c9101748 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 9 Jun 2026 16:18:02 -0400 Subject: [PATCH 02/38] feat(orchestrator): agent prompts + mini-skills for the integration flow Agent prompts (agents/) and paired single-purpose mini-skills (skills/) for the task-queue orchestrator: install, init, identify, error-tracking, plan-capture, capture, build, dashboard, report, plus the integrate-posthog seed. Mini-skills are grounded in PostHog docs via docs_urls + {references}. Co-Authored-By: Claude Opus 4.8 (1M context) --- transformation-config/agents/build.md | 23 +++++++++++++++ transformation-config/agents/capture.md | 19 +++++++++++++ transformation-config/agents/dashboard.md | 19 +++++++++++++ .../agents/error-tracking.md | 20 +++++++++++++ transformation-config/agents/example.md | 22 +++++++++++++++ transformation-config/agents/identify.md | 19 +++++++++++++ transformation-config/agents/init.md | 20 +++++++++++++ transformation-config/agents/install.md | 20 +++++++++++++ .../agents/integrate-posthog.md | 28 +++++++++++++++++++ transformation-config/agents/plan-capture.md | 21 ++++++++++++++ transformation-config/agents/report.md | 21 ++++++++++++++ .../skills/build/config.yaml | 9 ++++++ .../skills/build/description.md | 24 ++++++++++++++++ .../skills/capture/config.yaml | 11 ++++++++ .../skills/capture/description.md | 15 ++++++++++ .../skills/dashboard/config.yaml | 9 ++++++ .../skills/dashboard/description.md | 11 ++++++++ .../skills/error-tracking-step/config.yaml | 11 ++++++++ .../skills/error-tracking-step/description.md | 16 +++++++++++ .../skills/identify/config.yaml | 10 +++++++ .../skills/identify/description.md | 16 +++++++++++ transformation-config/skills/init/config.yaml | 11 ++++++++ .../skills/init/description.md | 28 +++++++++++++++++++ .../skills/install/config.yaml | 11 ++++++++ .../skills/install/description.md | 19 +++++++++++++ .../skills/plan-capture/config.yaml | 10 +++++++ .../skills/plan-capture/description.md | 17 +++++++++++ .../skills/report/config.yaml | 9 ++++++ .../skills/report/description.md | 19 +++++++++++++ 29 files changed, 488 insertions(+) create mode 100644 transformation-config/agents/build.md create mode 100644 transformation-config/agents/capture.md create mode 100644 transformation-config/agents/dashboard.md create mode 100644 transformation-config/agents/error-tracking.md create mode 100644 transformation-config/agents/example.md create mode 100644 transformation-config/agents/identify.md create mode 100644 transformation-config/agents/init.md create mode 100644 transformation-config/agents/install.md create mode 100644 transformation-config/agents/integrate-posthog.md create mode 100644 transformation-config/agents/plan-capture.md create mode 100644 transformation-config/agents/report.md create mode 100644 transformation-config/skills/build/config.yaml create mode 100644 transformation-config/skills/build/description.md create mode 100644 transformation-config/skills/capture/config.yaml create mode 100644 transformation-config/skills/capture/description.md create mode 100644 transformation-config/skills/dashboard/config.yaml create mode 100644 transformation-config/skills/dashboard/description.md create mode 100644 transformation-config/skills/error-tracking-step/config.yaml create mode 100644 transformation-config/skills/error-tracking-step/description.md create mode 100644 transformation-config/skills/identify/config.yaml create mode 100644 transformation-config/skills/identify/description.md create mode 100644 transformation-config/skills/init/config.yaml create mode 100644 transformation-config/skills/init/description.md create mode 100644 transformation-config/skills/install/config.yaml create mode 100644 transformation-config/skills/install/description.md create mode 100644 transformation-config/skills/plan-capture/config.yaml create mode 100644 transformation-config/skills/plan-capture/description.md create mode 100644 transformation-config/skills/report/config.yaml create mode 100644 transformation-config/skills/report/description.md diff --git a/transformation-config/agents/build.md b/transformation-config/agents/build.md new file mode 100644 index 00000000..fb028d68 --- /dev/null +++ b/transformation-config/agents/build.md @@ -0,0 +1,23 @@ +--- +type: build +label: Install dependencies and build +model: claude-sonnet-4-6 +skills: [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. Until now the steps only edited code and +the manifest — this is where it actually installs and compiles. + +## How you know you succeeded + +The install completes and the build (or typecheck) passes. 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/transformation-config/agents/capture.md b/transformation-config/agents/capture.md new file mode 100644 index 00000000..b4317135 --- /dev/null +++ b/transformation-config/agents/capture.md @@ -0,0 +1,19 @@ +--- +type: capture +label: Instrument the planned events +model: claude-sonnet-4-6 +skills: [capture] +allowedTools: [Read, Edit, Glob, Grep] +disallowedTools: [enqueue_task] +dependsOn: [plan-capture] +--- + +## Goal + +Instrument the events from the plan you were handed. Add a PostHog capture call at +each one, on the real user action. + +## How you know you succeeded + +Each planned event has a capture call that fires on the user action, not on page +load or render. If a planned event no longer fits the code, skip it and note why. diff --git a/transformation-config/agents/dashboard.md b/transformation-config/agents/dashboard.md new file mode 100644 index 00000000..3adb8b6d --- /dev/null +++ b/transformation-config/agents/dashboard.md @@ -0,0 +1,19 @@ +--- +type: dashboard +label: Create a starter dashboard +model: claude-sonnet-4-6 +skills: [dashboard] +allowedTools: [Read, Glob, Grep] +disallowedTools: [Write, Edit, Bash, enqueue_task] +dependsOn: [capture] +--- + +## 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/transformation-config/agents/error-tracking.md b/transformation-config/agents/error-tracking.md new file mode 100644 index 00000000..3d7ac2d6 --- /dev/null +++ b/transformation-config/agents/error-tracking.md @@ -0,0 +1,20 @@ +--- +type: error-tracking +label: Add error tracking +model: claude-sonnet-4-6 +skills: [error-tracking-step] +allowedTools: [Read, Edit, Glob, Grep] +disallowedTools: [enqueue_task] +dependsOn: [install, init] +--- + +## Goal + +Add PostHog error tracking around the app's critical flows and boundaries, so +failures that matter reach PostHog. + +## How you know you succeeded + +Exceptions in the important paths — the routes, actions, and boundaries where a +failure hurts the user — are captured. If the app already reports errors +elsewhere, add PostHog alongside it rather than replacing it. diff --git a/transformation-config/agents/example.md b/transformation-config/agents/example.md new file mode 100644 index 00000000..d028ee27 --- /dev/null +++ b/transformation-config/agents/example.md @@ -0,0 +1,22 @@ +--- +type: example +model: claude-haiku-4-5-20251001 +skills: [] +allowedTools: [Read, Glob, Grep] +disallowedTools: [enqueue_task] +dependsOn: [] +--- + +## Goal + +This is the canonical example of an agent prompt, the WHAT of an orchestrator +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. 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. + +## 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/transformation-config/agents/identify.md b/transformation-config/agents/identify.md new file mode 100644 index 00000000..28ccad11 --- /dev/null +++ b/transformation-config/agents/identify.md @@ -0,0 +1,19 @@ +--- +type: identify +label: Wire user identification +model: claude-sonnet-4-6 +skills: [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/transformation-config/agents/init.md b/transformation-config/agents/init.md new file mode 100644 index 00000000..b826089b --- /dev/null +++ b/transformation-config/agents/init.md @@ -0,0 +1,20 @@ +--- +type: init +label: Set up PostHog initialization +model: claude-haiku-4-5-20251001 +skills: [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/transformation-config/agents/install.md b/transformation-config/agents/install.md new file mode 100644 index 00000000..1ca1636e --- /dev/null +++ b/transformation-config/agents/install.md @@ -0,0 +1,20 @@ +--- +type: install +label: Add the PostHog SDK to the manifest +model: claude-haiku-4-5-20251001 +skills: [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/transformation-config/agents/integrate-posthog.md b/transformation-config/agents/integrate-posthog.md new file mode 100644 index 00000000..8564a81f --- /dev/null +++ b/transformation-config/agents/integrate-posthog.md @@ -0,0 +1,28 @@ +--- +type: integrate-posthog +model: claude-sonnet-4-6 +skills: [] +allowedTools: [Read, Glob, Grep] +disallowedTools: [Write, Edit, Bash, complete_task] +dependsOn: [] +--- + +## Goal + +Plan a PostHog integration for this project and seed the task queue. Take a brief +glance at the repo to confirm its shape — a quick look, not a deep analysis — +then seed this graph: + +- `install` and `init`, independent of each other. +- `identify`, `error-tracking`, and `plan-capture`, each after `install` and + `init`, independent of each other. +- `capture`, after `plan-capture`. +- `build`, after `install`, `init`, `identify`, `error-tracking`, and `capture` — + it installs the dependencies and verifies the project compiles. +- `dashboard`, after `capture`. +- `report`, after `build` and `dashboard` — it writes the setup report last. + +## How you know you succeeded + +The nine tasks are queued with that dependency shape, and the first is runnable. +Keep them small and discrete so each finishes fast and shows visible progress. diff --git a/transformation-config/agents/plan-capture.md b/transformation-config/agents/plan-capture.md new file mode 100644 index 00000000..fc49c572 --- /dev/null +++ b/transformation-config/agents/plan-capture.md @@ -0,0 +1,21 @@ +--- +type: plan-capture +label: Plan which events to capture +model: claude-sonnet-4-6 +skills: [plan-capture] +allowedTools: [Read, Glob, Grep] +disallowedTools: [Write, Edit, Bash, enqueue_task] +dependsOn: [install, init] +--- + +## Goal + +Decide which events are worth capturing in this app. Read the code to find the +meaningful user actions — the things a product team would want to measure — and +hand off that list. Do not edit code. + +## How you know you succeeded + +Your handoff is a short, concrete event plan: a handful of named events, each +tied to a real user action and the file where it happens. Prefer a few +high-signal events over an exhaustive list. diff --git a/transformation-config/agents/report.md b/transformation-config/agents/report.md new file mode 100644 index 00000000..fdac07d7 --- /dev/null +++ b/transformation-config/agents/report.md @@ -0,0 +1,21 @@ +--- +type: report +label: Write the setup report +model: claude-sonnet-4-6 +skills: [report] +allowedTools: [Read, Write, Glob, Grep] +disallowedTools: [enqueue_task] +dependsOn: [build, dashboard] +--- + +## Goal + +Write the setup report summarizing what this integration did, drawing on the +handoffs from the previous steps. + +## 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/transformation-config/skills/build/config.yaml b/transformation-config/skills/build/config.yaml new file mode 100644 index 00000000..82142d68 --- /dev/null +++ b/transformation-config/skills/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/transformation-config/skills/build/description.md b/transformation-config/skills/build/description.md new file mode 100644 index 00000000..dfeb018f --- /dev/null +++ b/transformation-config/skills/build/description.md @@ -0,0 +1,24 @@ +# Install and build + +Bring the integration together: install the declared dependencies, then verify the +project builds. + +## Install + +Detect the package manager from the lockfile — `pnpm-lock.yaml` → pnpm, +`yarn.lock` → yarn, `bun.lockb` → bun, otherwise npm — and run its install. The +manifest already declares PostHog from the install step; you are realizing it now. + +## Build and verify + +Run the project's build or typecheck script if one exists (check the manifest's +scripts for `build`, `typecheck`, `tsc`). Fix straightforward issues from the new +PostHog code — a missing import, a wrong call shape. + +## Conflicts + +If install or build surfaces a conflict you cannot cleanly resolve — a peer +dependency clash, a version conflict, a build error you should not paper over — +stop forcing it. Summarize it in one line in your handoff `conflict` field, and +put the full detail and what you tried in `did`. The user sees the one-liner in +the outro and the detail in the report. diff --git a/transformation-config/skills/capture/config.yaml b/transformation-config/skills/capture/config.yaml new file mode 100644 index 00000000..8f973906 --- /dev/null +++ b/transformation-config/skills/capture/config.yaml @@ -0,0 +1,11 @@ +type: docs-only +template: description.md +description: Instrument the planned events with posthog.capture +tags: [orchestrator, capture] +variants: + - id: all + display_name: PostHog capture step + tags: [orchestrator, capture] + docs_urls: + - https://posthog.com/docs/libraries/js.md + - https://posthog.com/docs/product-analytics/best-practices.md diff --git a/transformation-config/skills/capture/description.md b/transformation-config/skills/capture/description.md new file mode 100644 index 00000000..d042de8b --- /dev/null +++ b/transformation-config/skills/capture/description.md @@ -0,0 +1,15 @@ +# Capture events + +Instrument the planned events with `posthog.capture('event_name', { ...props })`. + +- Fire each capture on the real user action — the click or submit handler, the + server action — not on render or page load. +- Add properties that make the event useful to analyze. +- Read the file before editing, and check the event is not already captured, so a + re-run does not double-instrument. + +Use the event plan from the previous step for the names, files, and actions. + +## Reference + +{references} diff --git a/transformation-config/skills/dashboard/config.yaml b/transformation-config/skills/dashboard/config.yaml new file mode 100644 index 00000000..affa5328 --- /dev/null +++ b/transformation-config/skills/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/transformation-config/skills/dashboard/description.md b/transformation-config/skills/dashboard/description.md new file mode 100644 index 00000000..71e580c5 --- /dev/null +++ b/transformation-config/skills/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/transformation-config/skills/error-tracking-step/config.yaml b/transformation-config/skills/error-tracking-step/config.yaml new file mode 100644 index 00000000..ec9aea97 --- /dev/null +++ b/transformation-config/skills/error-tracking-step/config.yaml @@ -0,0 +1,11 @@ +type: docs-only +template: description.md +description: Capture exceptions with PostHog around critical flows +tags: [orchestrator, error-tracking] +variants: + - id: all + display_name: PostHog error-tracking step + tags: [orchestrator, error-tracking] + docs_urls: + - https://posthog.com/docs/error-tracking/installation/web.md + - https://posthog.com/docs/error-tracking/installation/node.md diff --git a/transformation-config/skills/error-tracking-step/description.md b/transformation-config/skills/error-tracking-step/description.md new file mode 100644 index 00000000..ccc70121 --- /dev/null +++ b/transformation-config/skills/error-tracking-step/description.md @@ -0,0 +1,16 @@ +# Add error tracking + +Capture exceptions with PostHog at the points where failures matter. + +- Wrap the critical paths: server route handlers, server actions, payment, + webhook and auth endpoints, and client error boundaries. +- Use `posthog.captureException(error, { ...context })` in the catch blocks, + with enough context to debug. +- Do not swallow errors — capture, then handle or re-throw as the code already + does. +- Read the file before editing, and add PostHog alongside any existing error + reporting rather than replacing it. + +## Reference + +{references} diff --git a/transformation-config/skills/identify/config.yaml b/transformation-config/skills/identify/config.yaml new file mode 100644 index 00000000..ed046697 --- /dev/null +++ b/transformation-config/skills/identify/config.yaml @@ -0,0 +1,10 @@ +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 diff --git a/transformation-config/skills/identify/description.md b/transformation-config/skills/identify/description.md new file mode 100644 index 00000000..8b4240c2 --- /dev/null +++ b/transformation-config/skills/identify/description.md @@ -0,0 +1,16 @@ +# Identify users + +Call `posthog.identify` 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. +- Pass useful person properties (email, name, plan) as the second argument. +- Call `posthog.reset()` on logout 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. + +## Reference + +{references} diff --git a/transformation-config/skills/init/config.yaml b/transformation-config/skills/init/config.yaml new file mode 100644 index 00000000..0317ac8e --- /dev/null +++ b/transformation-config/skills/init/config.yaml @@ -0,0 +1,11 @@ +type: docs-only +template: description.md +description: Initialize PostHog and set its environment variables +tags: [orchestrator, init] +variants: + - id: all + display_name: PostHog init step + tags: [orchestrator, init] + docs_urls: + - https://posthog.com/docs/libraries/js.md + - https://posthog.com/docs/libraries/node.md diff --git a/transformation-config/skills/init/description.md b/transformation-config/skills/init/description.md new file mode 100644 index 00000000..7af55ea7 --- /dev/null +++ b/transformation-config/skills/init/description.md @@ -0,0 +1,28 @@ +# 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 convention so the client can read them: +`NEXT_PUBLIC_` for Next.js, `VITE_` for Vite, `PUBLIC_` for SvelteKit. + +- the public project token +- the PostHog host + +## Init point + +Create the framework's single initialization point that runs once on the client: + +- **Next.js App Router**: a client `PostHogProvider` that calls `posthog.init` + with the env key and host, wrapping the app in the root layout. +- **Other frameworks**: the equivalent provider or bootstrap that initializes + PostHog once. + +Read the existing provider or layout before editing, and add PostHog alongside +what is already there rather than replacing it. + +## Reference + +{references} diff --git a/transformation-config/skills/install/config.yaml b/transformation-config/skills/install/config.yaml new file mode 100644 index 00000000..a442772b --- /dev/null +++ b/transformation-config/skills/install/config.yaml @@ -0,0 +1,11 @@ +type: docs-only +template: description.md +description: Install the PostHog SDK with the project's package manager +tags: [orchestrator, install] +variants: + - id: all + display_name: PostHog install step + tags: [orchestrator, install] + docs_urls: + - https://posthog.com/docs/libraries/js.md + - https://posthog.com/docs/libraries/node.md diff --git a/transformation-config/skills/install/description.md b/transformation-config/skills/install/description.md new file mode 100644 index 00000000..624f4667 --- /dev/null +++ b/transformation-config/skills/install/description.md @@ -0,0 +1,19 @@ +# 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. + +- For a web or JavaScript framework app, add `posthog-js` to `dependencies`. +- If the app has server-side code that should send events, also add + `posthog-node`. +- Use a current, valid version range (e.g. `^1.x` for posthog-js). Match the + style of the other 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/transformation-config/skills/plan-capture/config.yaml b/transformation-config/skills/plan-capture/config.yaml new file mode 100644 index 00000000..b8d28e59 --- /dev/null +++ b/transformation-config/skills/plan-capture/config.yaml @@ -0,0 +1,10 @@ +type: docs-only +template: description.md +description: Decide which custom events are worth capturing +tags: [orchestrator, plan-capture] +variants: + - id: all + display_name: PostHog capture-planning step + tags: [orchestrator, plan-capture] + docs_urls: + - https://posthog.com/docs/product-analytics/best-practices.md diff --git a/transformation-config/skills/plan-capture/description.md b/transformation-config/skills/plan-capture/description.md new file mode 100644 index 00000000..770f0957 --- /dev/null +++ b/transformation-config/skills/plan-capture/description.md @@ -0,0 +1,17 @@ +# Plan what to capture + +Read the app and decide which custom events are worth capturing. You are +planning, not editing. + +Look for the actions that matter to a product team: signups, key feature use, +content created, purchases, sharing, settings changed. Skip low-value noise and +anything autocapture already covers (generic clicks, pageviews). + +For each event choose a clear, consistent name — `lower_snake_case`, named for +the action — and note the file and the user action that should trigger it. A few +high-signal events beat a long list. Hand off the plan so the capture step can +instrument it. + +## Reference + +{references} diff --git a/transformation-config/skills/report/config.yaml b/transformation-config/skills/report/config.yaml new file mode 100644 index 00000000..1c454835 --- /dev/null +++ b/transformation-config/skills/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/transformation-config/skills/report/description.md b/transformation-config/skills/report/description.md new file mode 100644 index 00000000..e25633a8 --- /dev/null +++ b/transformation-config/skills/report/description.md @@ -0,0 +1,19 @@ +# Write the setup report + +Write `posthog-setup-report.md` at the project root summarizing the integration. +The handoffs from the previous steps are given to you as context — draw the +details from them. + +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, the file. +- Whether user identification was wired or skipped, and why. +- The error tracking added. +- The dashboard link. +- Any build conflict, in full — the build step's handoff names it, and the user + needs the detail here. +- Clear next steps for the user. + +Keep it skimmable. This is the artifact the user opens after the run. From ba5146530afb6eac5369c692f871204db80cfdaa Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 9 Jun 2026 18:17:51 -0400 Subject: [PATCH 03/38] refine the orchestrator integration flow Merges plan-capture into capture (one pass, writes .posthog-events.json for the event-plan view and the report); makes error-tracking a single global boundary; orders dashboard and report after build, which now also lints and tests; install stays manifest-only and build flags out-of-scope conflicts and moves on; report draws on the queue log and the events file; the docs-only skills drop framework specifics in favor of the bundled docs and examples. Co-Authored-By: Claude Opus 4.8 (1M context) --- transformation-config/agents/build.md | 7 ++-- transformation-config/agents/capture.md | 14 ++++---- transformation-config/agents/dashboard.md | 2 +- .../agents/error-tracking.md | 14 ++++---- .../agents/integrate-posthog.md | 19 ++++++----- transformation-config/agents/plan-capture.md | 21 ------------ transformation-config/agents/report.md | 6 ++-- .../skills/build/description.md | 31 ++++++++++-------- .../skills/capture/description.md | 32 ++++++++++++++----- .../skills/error-tracking-step/description.md | 15 ++++----- .../skills/init/description.md | 18 ++++------- .../skills/install/description.md | 9 +++--- .../skills/plan-capture/config.yaml | 10 ------ .../skills/plan-capture/description.md | 17 ---------- .../skills/report/description.md | 14 +++++--- 15 files changed, 100 insertions(+), 129 deletions(-) delete mode 100644 transformation-config/agents/plan-capture.md delete mode 100644 transformation-config/skills/plan-capture/config.yaml delete mode 100644 transformation-config/skills/plan-capture/description.md diff --git a/transformation-config/agents/build.md b/transformation-config/agents/build.md index fb028d68..348bb5d3 100644 --- a/transformation-config/agents/build.md +++ b/transformation-config/agents/build.md @@ -11,12 +11,13 @@ dependsOn: [install, init, identify, error-tracking, capture] ## Goal Bring the integration together: install the dependencies the earlier steps -declared, then verify the project builds. Until now the steps only edited code and -the manifest — this is where it actually installs and compiles. +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 (or typecheck) passes. If you hit a conflict +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 diff --git a/transformation-config/agents/capture.md b/transformation-config/agents/capture.md index b4317135..477c5d8b 100644 --- a/transformation-config/agents/capture.md +++ b/transformation-config/agents/capture.md @@ -1,19 +1,21 @@ --- type: capture -label: Instrument the planned events +label: Capture events model: claude-sonnet-4-6 skills: [capture] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] -dependsOn: [plan-capture] +dependsOn: [install, init] --- ## Goal -Instrument the events from the plan you were handed. Add a PostHog capture call at -each one, on the real user action. +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 -Each planned event has a capture call that fires on the user action, not on page -load or render. If a planned event no longer fits the code, skip it and note why. +The meaningful user actions across the app have capture calls that fire on the +real action, not on page load, and `.posthog-events.json` lists the events you +instrumented. diff --git a/transformation-config/agents/dashboard.md b/transformation-config/agents/dashboard.md index 3adb8b6d..1cc2a887 100644 --- a/transformation-config/agents/dashboard.md +++ b/transformation-config/agents/dashboard.md @@ -5,7 +5,7 @@ model: claude-sonnet-4-6 skills: [dashboard] allowedTools: [Read, Glob, Grep] disallowedTools: [Write, Edit, Bash, enqueue_task] -dependsOn: [capture] +dependsOn: [build] --- ## Goal diff --git a/transformation-config/agents/error-tracking.md b/transformation-config/agents/error-tracking.md index 3d7ac2d6..eae9d9ec 100644 --- a/transformation-config/agents/error-tracking.md +++ b/transformation-config/agents/error-tracking.md @@ -3,18 +3,18 @@ type: error-tracking label: Add error tracking model: claude-sonnet-4-6 skills: [error-tracking-step] -allowedTools: [Read, Edit, Glob, Grep] +allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] -dependsOn: [install, init] +dependsOn: [capture] --- ## Goal -Add PostHog error tracking around the app's critical flows and boundaries, so -failures that matter reach PostHog. +Set up the framework's single global error boundary so uncaught errors reach +PostHog. One place, following the docs and the reference example — not manual +capture calls sprinkled across files. ## How you know you succeeded -Exceptions in the important paths — the routes, actions, and boundaries where a -failure hurts the user — are captured. If the app already reports errors -elsewhere, add PostHog alongside it rather than replacing it. +A global error handler forwards exceptions to PostHog. You did not read through the +whole app or hand-wrap individual components or routes. diff --git a/transformation-config/agents/integrate-posthog.md b/transformation-config/agents/integrate-posthog.md index 8564a81f..35fa9aed 100644 --- a/transformation-config/agents/integrate-posthog.md +++ b/transformation-config/agents/integrate-posthog.md @@ -14,15 +14,18 @@ glance at the repo to confirm its shape — a quick look, not a deep analysis then seed this graph: - `install` and `init`, independent of each other. -- `identify`, `error-tracking`, and `plan-capture`, each after `install` and - `init`, independent of each other. -- `capture`, after `plan-capture`. -- `build`, after `install`, `init`, `identify`, `error-tracking`, and `capture` — - it installs the dependencies and verifies the project compiles. -- `dashboard`, after `capture`. -- `report`, after `build` and `dashboard` — it writes the setup report last. +- `identify` and `capture`, each after `install` and `init`, independent of each + other. `capture` both decides the events and instruments them. +- `error-tracking`, after `capture` — event tracking goes in first, then the + global error boundary. +- `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 -The nine tasks are queued with that dependency shape, and the first is runnable. +The tasks are queued with that dependency shape, and the first is runnable. Keep them small and discrete so each finishes fast and shows visible progress. diff --git a/transformation-config/agents/plan-capture.md b/transformation-config/agents/plan-capture.md deleted file mode 100644 index fc49c572..00000000 --- a/transformation-config/agents/plan-capture.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -type: plan-capture -label: Plan which events to capture -model: claude-sonnet-4-6 -skills: [plan-capture] -allowedTools: [Read, Glob, Grep] -disallowedTools: [Write, Edit, Bash, enqueue_task] -dependsOn: [install, init] ---- - -## Goal - -Decide which events are worth capturing in this app. Read the code to find the -meaningful user actions — the things a product team would want to measure — and -hand off that list. Do not edit code. - -## How you know you succeeded - -Your handoff is a short, concrete event plan: a handful of named events, each -tied to a real user action and the file where it happens. Prefer a few -high-signal events over an exhaustive list. diff --git a/transformation-config/agents/report.md b/transformation-config/agents/report.md index fdac07d7..8a49b13d 100644 --- a/transformation-config/agents/report.md +++ b/transformation-config/agents/report.md @@ -5,13 +5,13 @@ model: claude-sonnet-4-6 skills: [report] allowedTools: [Read, Write, Glob, Grep] disallowedTools: [enqueue_task] -dependsOn: [build, dashboard] +dependsOn: [dashboard] --- ## Goal -Write the setup report summarizing what this integration did, drawing on the -handoffs from the previous steps. +Write the setup report summarizing what this integration did, drawing only on the +run's queue log (`.posthog-wizard/`) and the local `.posthog-events.json`. ## How you know you succeeded diff --git a/transformation-config/skills/build/description.md b/transformation-config/skills/build/description.md index dfeb018f..78f40899 100644 --- a/transformation-config/skills/build/description.md +++ b/transformation-config/skills/build/description.md @@ -1,24 +1,27 @@ # Install and build -Bring the integration together: install the declared dependencies, then verify the -project builds. +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 lockfile — `pnpm-lock.yaml` → pnpm, -`yarn.lock` → yarn, `bun.lockb` → bun, otherwise npm — and run its install. The -manifest already declares PostHog from the install step; you are realizing it now. +Detect the package manager from the project's lockfile and run its install once, +in this project directory. The manifest already declares PostHog. ## Build and verify -Run the project's build or typecheck script if one exists (check the manifest's -scripts for `build`, `typecheck`, `tsc`). Fix straightforward issues from the new -PostHog code — a missing import, a wrong call shape. +Run the project's build (or typecheck), lint, and test scripts if they exist +(check the manifest's scripts). Fix only obvious issues from the new PostHog code — +a missing import, a wrong call shape. -## Conflicts +## Flag out-of-scope conflicts and move on -If install or build surfaces a conflict you cannot cleanly resolve — a peer -dependency clash, a version conflict, a build error you should not paper over — -stop forcing it. Summarize it in one line in your handoff `conflict` field, and -put the full detail and what you tried in `did`. The user sees the one-liner in -the outro and the detail in the report. +Work only within this project's own directory; other repos and directories are not +part of this task. + +If you hit a conflict that is excessively difficult and outside the scope of this +integration — a dependency clash, a pre-existing build break, an environment issue +that is not about the PostHog code — flag it and move on rather than spend time +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; flagging it is the right outcome. diff --git a/transformation-config/skills/capture/description.md b/transformation-config/skills/capture/description.md index d042de8b..43176247 100644 --- a/transformation-config/skills/capture/description.md +++ b/transformation-config/skills/capture/description.md @@ -1,14 +1,30 @@ -# Capture events +# Plan and capture events -Instrument the planned events with `posthog.capture('event_name', { ...props })`. +Decide which custom events are worth capturing, then instrument them — in one +pass, reading each file once. -- Fire each capture on the real user action — the click or submit handler, the - server action — not on render or page load. -- Add properties that make the event useful to analyze. -- Read the file before editing, and check the event is not already captured, so a - re-run does not double-instrument. +## Choose and record -Use the event plan from the previous step for the names, files, and actions. +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). Don't duplicate events that +already exist. Server-side events are required if there is instrumentable +server-side code (API routes, server actions): payment/checkout completion, +webhook handlers, and auth endpoints. + +Write the chosen events to `.posthog-events.json` at the project root — a JSON +array of `{ event, description, file }`, one entry per event. 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 add `posthog.capture('event_name', { ...props })` 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. + +Leave `.posthog-events.json` in place for the report. ## Reference diff --git a/transformation-config/skills/error-tracking-step/description.md b/transformation-config/skills/error-tracking-step/description.md index ccc70121..2670a024 100644 --- a/transformation-config/skills/error-tracking-step/description.md +++ b/transformation-config/skills/error-tracking-step/description.md @@ -1,15 +1,12 @@ # Add error tracking -Capture exceptions with PostHog at the points where failures matter. +Set up the framework's GLOBAL error boundary so uncaught errors and exceptions +reach PostHog — one handler, not hand-wrapped across files. -- Wrap the critical paths: server route handlers, server actions, payment, - webhook and auth endpoints, and client error boundaries. -- Use `posthog.captureException(error, { ...context })` in the catch blocks, - with enough context to debug. -- Do not swallow errors — capture, then handle or re-throw as the code already - does. -- Read the file before editing, and add PostHog alongside any existing error - reporting rather than replacing it. +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, and you are done. One handler is enough — do not read +through the whole app or wrap individual components or routes by hand. ## Reference diff --git a/transformation-config/skills/init/description.md b/transformation-config/skills/init/description.md index 7af55ea7..2440423e 100644 --- a/transformation-config/skills/init/description.md +++ b/transformation-config/skills/init/description.md @@ -4,24 +4,18 @@ 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 convention so the client can read them: -`NEXT_PUBLIC_` for Next.js, `VITE_` for Vite, `PUBLIC_` for SvelteKit. +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: - -- **Next.js App Router**: a client `PostHogProvider` that calls `posthog.init` - with the env key and host, wrapping the app in the root layout. -- **Other frameworks**: the equivalent provider or bootstrap that initializes - PostHog once. - -Read the existing provider or layout before editing, and add PostHog alongside -what is already there rather than replacing it. +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 diff --git a/transformation-config/skills/install/description.md b/transformation-config/skills/install/description.md index 624f4667..f914b263 100644 --- a/transformation-config/skills/install/description.md +++ b/transformation-config/skills/install/description.md @@ -5,11 +5,10 @@ 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. -- For a web or JavaScript framework app, add `posthog-js` to `dependencies`. -- If the app has server-side code that should send events, also add - `posthog-node`. -- Use a current, valid version range (e.g. `^1.x` for posthog-js). Match the - style of the other dependencies already in the manifest. +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. diff --git a/transformation-config/skills/plan-capture/config.yaml b/transformation-config/skills/plan-capture/config.yaml deleted file mode 100644 index b8d28e59..00000000 --- a/transformation-config/skills/plan-capture/config.yaml +++ /dev/null @@ -1,10 +0,0 @@ -type: docs-only -template: description.md -description: Decide which custom events are worth capturing -tags: [orchestrator, plan-capture] -variants: - - id: all - display_name: PostHog capture-planning step - tags: [orchestrator, plan-capture] - docs_urls: - - https://posthog.com/docs/product-analytics/best-practices.md diff --git a/transformation-config/skills/plan-capture/description.md b/transformation-config/skills/plan-capture/description.md deleted file mode 100644 index 770f0957..00000000 --- a/transformation-config/skills/plan-capture/description.md +++ /dev/null @@ -1,17 +0,0 @@ -# Plan what to capture - -Read the app and decide which custom events are worth capturing. You are -planning, not editing. - -Look for the actions that matter to a product team: signups, key feature use, -content created, purchases, sharing, settings changed. Skip low-value noise and -anything autocapture already covers (generic clicks, pageviews). - -For each event choose a clear, consistent name — `lower_snake_case`, named for -the action — and note the file and the user action that should trigger it. A few -high-signal events beat a long list. Hand off the plan so the capture step can -instrument it. - -## Reference - -{references} diff --git a/transformation-config/skills/report/description.md b/transformation-config/skills/report/description.md index e25633a8..b73d1258 100644 --- a/transformation-config/skills/report/description.md +++ b/transformation-config/skills/report/description.md @@ -1,19 +1,23 @@ # Write the setup report Write `posthog-setup-report.md` at the project root summarizing the integration. -The handoffs from the previous steps are given to you as context — draw the -details from them. +Draw on two sources only: + +- the run's queue log — `.posthog-wizard/queue.json` and the handoffs under + `.posthog-wizard/handoffs/` — for what each step did, whether identify was wired + or skipped, and any build conflict; +- `.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, the file. +- The events instrumented, as a table: event name, what it measures, and the file + (from `.posthog-events.json`). - Whether user identification was wired or skipped, and why. - The error tracking added. - The dashboard link. -- Any build conflict, in full — the build step's handoff names it, and the user - needs the detail here. +- Any build conflict, in full. - Clear next steps for the user. Keep it skimmable. This is the artifact the user opens after the run. From b8e66ecc48d30d61ad8bd09b8f91c24e8a04451a Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 10 Jun 2026 15:24:26 -0400 Subject: [PATCH 04/38] =?UTF-8?q?feat(agents):=20per-flow=20registry=20mar?= =?UTF-8?q?kers=20=E2=80=94=20flow=20+=20seed=20frontmatter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every agent names its flow (the program id) and each flow marks exactly one prompt seed: true, the planner. The wizard's registry is scoped per flow, so audit and migration flows can ship their own agent sets alongside these. The canonical example moves to a README served to authors, not the menu — the build skips it, so 'example' is no longer an installable agent. Co-Authored-By: Claude Opus 4.8 (1M context) --- scripts/lib/agent-generator.js | 3 +- transformation-config/agents/README.md | 37 +++++++++++++++++++ transformation-config/agents/build.md | 1 + transformation-config/agents/capture.md | 1 + transformation-config/agents/dashboard.md | 1 + .../agents/error-tracking.md | 1 + transformation-config/agents/example.md | 22 ----------- transformation-config/agents/identify.md | 1 + transformation-config/agents/init.md | 1 + transformation-config/agents/install.md | 1 + .../agents/integrate-posthog.md | 2 + transformation-config/agents/report.md | 1 + 12 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 transformation-config/agents/README.md delete mode 100644 transformation-config/agents/example.md diff --git a/scripts/lib/agent-generator.js b/scripts/lib/agent-generator.js index f84b912c..d404eeab 100644 --- a/scripts/lib/agent-generator.js +++ b/scripts/lib/agent-generator.js @@ -23,7 +23,8 @@ export function loadAgentIds(agentsSourceDir) { if (!fs.existsSync(agentsSourceDir)) return []; return fs .readdirSync(agentsSourceDir) - .filter(f => f.endsWith('.md')) + // 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(); } diff --git a/transformation-config/agents/README.md b/transformation-config/agents/README.md new file mode 100644 index 00000000..0737511d --- /dev/null +++ b/transformation-config/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/transformation-config/agents/build.md b/transformation-config/agents/build.md index 348bb5d3..e4c97add 100644 --- a/transformation-config/agents/build.md +++ b/transformation-config/agents/build.md @@ -1,5 +1,6 @@ --- type: build +flow: posthog-integration label: Install dependencies and build model: claude-sonnet-4-6 skills: [build] diff --git a/transformation-config/agents/capture.md b/transformation-config/agents/capture.md index 477c5d8b..08b0cfcf 100644 --- a/transformation-config/agents/capture.md +++ b/transformation-config/agents/capture.md @@ -1,5 +1,6 @@ --- type: capture +flow: posthog-integration label: Capture events model: claude-sonnet-4-6 skills: [capture] diff --git a/transformation-config/agents/dashboard.md b/transformation-config/agents/dashboard.md index 1cc2a887..7dcb0745 100644 --- a/transformation-config/agents/dashboard.md +++ b/transformation-config/agents/dashboard.md @@ -1,5 +1,6 @@ --- type: dashboard +flow: posthog-integration label: Create a starter dashboard model: claude-sonnet-4-6 skills: [dashboard] diff --git a/transformation-config/agents/error-tracking.md b/transformation-config/agents/error-tracking.md index eae9d9ec..4b859d63 100644 --- a/transformation-config/agents/error-tracking.md +++ b/transformation-config/agents/error-tracking.md @@ -1,5 +1,6 @@ --- type: error-tracking +flow: posthog-integration label: Add error tracking model: claude-sonnet-4-6 skills: [error-tracking-step] diff --git a/transformation-config/agents/example.md b/transformation-config/agents/example.md deleted file mode 100644 index d028ee27..00000000 --- a/transformation-config/agents/example.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -type: example -model: claude-haiku-4-5-20251001 -skills: [] -allowedTools: [Read, Glob, Grep] -disallowedTools: [enqueue_task] -dependsOn: [] ---- - -## Goal - -This is the canonical example of an agent prompt, the WHAT of an orchestrator -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. 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. - -## 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/transformation-config/agents/identify.md b/transformation-config/agents/identify.md index 28ccad11..70f8ecad 100644 --- a/transformation-config/agents/identify.md +++ b/transformation-config/agents/identify.md @@ -1,5 +1,6 @@ --- type: identify +flow: posthog-integration label: Wire user identification model: claude-sonnet-4-6 skills: [identify] diff --git a/transformation-config/agents/init.md b/transformation-config/agents/init.md index b826089b..052b87fc 100644 --- a/transformation-config/agents/init.md +++ b/transformation-config/agents/init.md @@ -1,5 +1,6 @@ --- type: init +flow: posthog-integration label: Set up PostHog initialization model: claude-haiku-4-5-20251001 skills: [init] diff --git a/transformation-config/agents/install.md b/transformation-config/agents/install.md index 1ca1636e..e11fa69d 100644 --- a/transformation-config/agents/install.md +++ b/transformation-config/agents/install.md @@ -1,5 +1,6 @@ --- type: install +flow: posthog-integration label: Add the PostHog SDK to the manifest model: claude-haiku-4-5-20251001 skills: [install] diff --git a/transformation-config/agents/integrate-posthog.md b/transformation-config/agents/integrate-posthog.md index 35fa9aed..03306fb1 100644 --- a/transformation-config/agents/integrate-posthog.md +++ b/transformation-config/agents/integrate-posthog.md @@ -1,5 +1,7 @@ --- type: integrate-posthog +flow: posthog-integration +seed: true model: claude-sonnet-4-6 skills: [] allowedTools: [Read, Glob, Grep] diff --git a/transformation-config/agents/report.md b/transformation-config/agents/report.md index 8a49b13d..19a8cc62 100644 --- a/transformation-config/agents/report.md +++ b/transformation-config/agents/report.md @@ -1,5 +1,6 @@ --- type: report +flow: posthog-integration label: Write the setup report model: claude-sonnet-4-6 skills: [report] From 5ddce459b7ae9ddbbdcb65801c9dd0110ac863d9 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 10 Jun 2026 16:38:42 -0400 Subject: [PATCH 05/38] feat(skills): emit framework commandments as references/COMMANDMENTS.md The orchestrator installs the framework's integration skill as the run reference and points task agents at individual files, so the tag-matched rules need to exist outside the SKILL.md body. The file also joins the references listing. Co-Authored-By: Claude Opus 4.8 (1M context) --- scripts/lib/skill-generator.js | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/scripts/lib/skill-generator.js b/scripts/lib/skill-generator.js index 3a7d3dca..ed98f472 100644 --- a/scripts/lib/skill-generator.js +++ b/scripts/lib/skill-generator.js @@ -581,15 +581,30 @@ async function generateSkill({ } } + // 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 const workflowText = formatWorkflowSteps(workflows); From 0a62554ec4991cfa4c43dd015ad6b5cd833d6812 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 10 Jun 2026 17:00:55 -0400 Subject: [PATCH 06/38] feat(agents): dashboard is not a CI task MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ci: false in the dashboard frontmatter — CI runs must not create dashboards, so the wizard's registry drops the type there. The seed plans around missing types, rewiring dependents to the nearest upstream step. Co-Authored-By: Claude Opus 4.8 (1M context) --- transformation-config/agents/dashboard.md | 1 + transformation-config/agents/integrate-posthog.md | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/transformation-config/agents/dashboard.md b/transformation-config/agents/dashboard.md index 7dcb0745..bb027687 100644 --- a/transformation-config/agents/dashboard.md +++ b/transformation-config/agents/dashboard.md @@ -1,6 +1,7 @@ --- type: dashboard flow: posthog-integration +ci: false label: Create a starter dashboard model: claude-sonnet-4-6 skills: [dashboard] diff --git a/transformation-config/agents/integrate-posthog.md b/transformation-config/agents/integrate-posthog.md index 03306fb1..443e05fd 100644 --- a/transformation-config/agents/integrate-posthog.md +++ b/transformation-config/agents/integrate-posthog.md @@ -27,6 +27,10 @@ then seed this graph: linting, and testing cleanly. - `report`, after `dashboard` — it writes the setup report last. +Some task types are not available in every run — `enqueue_task` only accepts +the ones that are. Plan without the missing ones and rewire their dependents +to the nearest upstream step (no `dashboard` means `report` follows `build`). + ## How you know you succeeded The tasks are queued with that dependency shape, and the first is runnable. From 464c6fd7928d155d494846864e419201152319f5 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 10 Jun 2026 17:17:59 -0400 Subject: [PATCH 07/38] =?UTF-8?q?revert=20ci=20awareness=20from=20agent=20?= =?UTF-8?q?content=20=E2=80=94=20the=20harness=20owns=20run-mode=20policy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- transformation-config/agents/dashboard.md | 1 - 1 file changed, 1 deletion(-) diff --git a/transformation-config/agents/dashboard.md b/transformation-config/agents/dashboard.md index bb027687..7dcb0745 100644 --- a/transformation-config/agents/dashboard.md +++ b/transformation-config/agents/dashboard.md @@ -1,7 +1,6 @@ --- type: dashboard flow: posthog-integration -ci: false label: Create a starter dashboard model: claude-sonnet-4-6 skills: [dashboard] From 5a3d5e425d592fbccba2e340551833310edf2f0f Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 16 Jun 2026 20:24:16 -0400 Subject: [PATCH 08/38] feat(orchestrator): parallel error-tracking, seed full graph, cache paths Seed wires error-tracking after install+init (parallel with identify/ capture) instead of after capture; error-tracking agent is instrument-only (no install/build/test, stay in project). Seed prompt drops the "plan without the missing ones" hedge so the full chain (through report) is always queued. Report reads .posthog-wizard-cache/ (renamed cache dir). Co-Authored-By: Claude Fable 5 --- .../agents/error-tracking.md | 15 ++++++++++---- .../agents/integrate-posthog.md | 20 +++++++------------ transformation-config/agents/report.md | 2 +- .../skills/report/description.md | 4 ++-- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/transformation-config/agents/error-tracking.md b/transformation-config/agents/error-tracking.md index 4b859d63..c3489c07 100644 --- a/transformation-config/agents/error-tracking.md +++ b/transformation-config/agents/error-tracking.md @@ -6,16 +6,23 @@ model: claude-sonnet-4-6 skills: [error-tracking-step] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] -dependsOn: [capture] +dependsOn: [install, init] --- ## Goal Set up the framework's single global error boundary so uncaught errors reach -PostHog. One place, following the docs and the reference example — not manual -capture calls sprinkled across files. +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 read through the +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/transformation-config/agents/integrate-posthog.md b/transformation-config/agents/integrate-posthog.md index 443e05fd..904ef74f 100644 --- a/transformation-config/agents/integrate-posthog.md +++ b/transformation-config/agents/integrate-posthog.md @@ -11,15 +11,13 @@ dependsOn: [] ## Goal -Plan a PostHog integration for this project and seed the task queue. Take a brief -glance at the repo to confirm its shape — a quick look, not a deep analysis — -then seed this graph: +Plan a PostHog integration and seed the task queue with this graph: - `install` and `init`, independent of each other. -- `identify` and `capture`, each after `install` and `init`, independent of each - other. `capture` both decides the events and instruments them. -- `error-tracking`, after `capture` — event tracking goes in first, then the - global error boundary. +- `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. @@ -27,11 +25,7 @@ then seed this graph: linting, and testing cleanly. - `report`, after `dashboard` — it writes the setup report last. -Some task types are not available in every run — `enqueue_task` only accepts -the ones that are. Plan without the missing ones and rewire their dependents -to the nearest upstream step (no `dashboard` means `report` follows `build`). - ## How you know you succeeded -The tasks are queued with that dependency shape, and the first is runnable. -Keep them small and discrete so each finishes fast and shows visible progress. +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/transformation-config/agents/report.md b/transformation-config/agents/report.md index 19a8cc62..ed0c6747 100644 --- a/transformation-config/agents/report.md +++ b/transformation-config/agents/report.md @@ -12,7 +12,7 @@ dependsOn: [dashboard] ## Goal Write the setup report summarizing what this integration did, drawing only on the -run's queue log (`.posthog-wizard/`) and the local `.posthog-events.json`. +run's queue log (`.posthog-wizard-cache/`) and the local `.posthog-events.json`. ## How you know you succeeded diff --git a/transformation-config/skills/report/description.md b/transformation-config/skills/report/description.md index b73d1258..4cc554ed 100644 --- a/transformation-config/skills/report/description.md +++ b/transformation-config/skills/report/description.md @@ -3,8 +3,8 @@ Write `posthog-setup-report.md` at the project root summarizing the integration. Draw on two sources only: -- the run's queue log — `.posthog-wizard/queue.json` and the handoffs under - `.posthog-wizard/handoffs/` — for what each step did, whether identify was wired +- 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-events.json` — the events that were instrumented. From 8092ddbf0d58548bf07886423ca888dd0fbd7096 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 16 Jun 2026 20:34:36 -0400 Subject: [PATCH 09/38] fix(skills): SDK error integration + personless anon events error-tracking: use the framework's PostHog middleware / capture_exception(), never a hand-rolled middleware that builds exception events via capture(). capture: use the authed user's id; for unauthenticated actions emit a personless event instead of fabricating an 'anonymous' distinct id. Co-Authored-By: Claude Fable 5 --- .../skills/capture/description.md | 5 +++++ .../skills/error-tracking-step/description.md | 19 +++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/transformation-config/skills/capture/description.md b/transformation-config/skills/capture/description.md index 43176247..67a394d4 100644 --- a/transformation-config/skills/capture/description.md +++ b/transformation-config/skills/capture/description.md @@ -24,6 +24,11 @@ action — the click or submit handler, the server action — not on render or p 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-events.json` in place for the report. ## Reference diff --git a/transformation-config/skills/error-tracking-step/description.md b/transformation-config/skills/error-tracking-step/description.md index 2670a024..1511c94f 100644 --- a/transformation-config/skills/error-tracking-step/description.md +++ b/transformation-config/skills/error-tracking-step/description.md @@ -1,12 +1,19 @@ # 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. +Wire the framework's single global path for uncaught errors and exceptions to +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, and you are done. One handler is enough — do not read -through the whole app or wrap individual components or routes by hand. +Use the SDK's own integration; do not hand-roll one. Where the framework ships a +PostHog middleware or handler, add that — it captures exceptions and request +context for you (e.g. Django: +`posthog.integrations.django.PosthogContextMiddleware` in `MIDDLEWARE`). Where +you must capture manually, call `posthog.capture_exception(e)` from the +framework's central error handler — never hand-construct an exception event with +`posthog.capture(...)`. Follow the framework rules (COMMANDMENTS) and the +reference for the exact pattern. + +Find the init or app entry, wire it once, and you are done — don't read through +the whole app or wrap individual components or routes by hand. ## Reference From 3f7325e63d34d0360cad6b29ec93cb7ab9737027 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 16 Jun 2026 21:01:05 -0400 Subject: [PATCH 10/38] revert: drop hardcoded Django middleware prose from error-tracking-step Framework specifics belong in docs/variants, not a step's prose. The fixed reference (integration-) now carries the framework's EXAMPLE.md + COMMANDMENTS (incl. PosthogContextMiddleware), so the step stays generic. Co-Authored-By: Claude Fable 5 --- .../skills/error-tracking-step/description.md | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/transformation-config/skills/error-tracking-step/description.md b/transformation-config/skills/error-tracking-step/description.md index 1511c94f..2670a024 100644 --- a/transformation-config/skills/error-tracking-step/description.md +++ b/transformation-config/skills/error-tracking-step/description.md @@ -1,19 +1,12 @@ # Add error tracking -Wire the framework's single global path for uncaught errors and exceptions to -PostHog — one handler, not hand-wrapped across files. +Set up the framework's GLOBAL error boundary so uncaught errors and exceptions +reach PostHog — one handler, not hand-wrapped across files. -Use the SDK's own integration; do not hand-roll one. Where the framework ships a -PostHog middleware or handler, add that — it captures exceptions and request -context for you (e.g. Django: -`posthog.integrations.django.PosthogContextMiddleware` in `MIDDLEWARE`). Where -you must capture manually, call `posthog.capture_exception(e)` from the -framework's central error handler — never hand-construct an exception event with -`posthog.capture(...)`. Follow the framework rules (COMMANDMENTS) and the -reference for the exact pattern. - -Find the init or app entry, wire it once, and you are done — don't read through -the whole app or wrap individual components or routes by hand. +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, and you are done. One handler is enough — do not read +through the whole app or wrap individual components or routes by hand. ## Reference From 3a9a57daa44b3b7e8b660ea9462c70375e41d6f5 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 16 Jun 2026 21:38:41 -0400 Subject: [PATCH 11/38] fix(build skill): don't fight install, report and move on MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop the build agent flailing when install is slow/erroring: no offline-flag retries, no poking the package manager's global store/cache, nothing outside the project dir. A build/install it can't cleanly finish is fine as long as it's reported in the handoff conflict — reporting and moving on is the right outcome. Co-Authored-By: Claude Fable 5 --- .../skills/build/description.md | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/transformation-config/skills/build/description.md b/transformation-config/skills/build/description.md index 78f40899..208f295b 100644 --- a/transformation-config/skills/build/description.md +++ b/transformation-config/skills/build/description.md @@ -6,7 +6,10 @@ 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. +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 @@ -16,12 +19,14 @@ a missing import, a wrong call shape. ## Flag out-of-scope conflicts and move on -Work only within this project's own directory; other repos and directories are not -part of this task. - -If you hit a conflict that is excessively difficult and outside the scope of this -integration — a dependency clash, a pre-existing build break, an environment issue -that is not about the PostHog code — flag it and move on rather than spend time -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; flagging it is the right outcome. +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. From 08a91caf9f5751539cb17861dc21a6bc3c165445 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 16 Jun 2026 21:47:55 -0400 Subject: [PATCH 12/38] feat(docs): reference identity-resolution.md everywhere identity is Add https://posthog.com/docs/product-analytics/identity-resolution.md alongside identify-users.md in every skill/doc that bundles the identity doc (identify, integration, the omnibus instrument skills, the audit family, revenue-analytics, best-practices, and the docs.yaml inline doc) so every identity-touching agent gets the resolution guidance. Co-Authored-By: Claude Fable 5 --- transformation-config/docs.yaml | 1 + transformation-config/skills/audit-3000/config.yaml | 1 + transformation-config/skills/audit-identify/config.yaml | 1 + transformation-config/skills/audit/config.yaml | 1 + transformation-config/skills/events-audit/config.yaml | 1 + transformation-config/skills/identify/config.yaml | 1 + transformation-config/skills/integration/config.yaml | 1 + .../skills/omnibus/instrument-integration/config.yaml | 1 + .../skills/omnibus/instrument-product-analytics/config.yaml | 1 + transformation-config/skills/posthog-best-practices/config.yaml | 1 + transformation-config/skills/revenue-analytics/config.yaml | 1 + 11 files changed, 11 insertions(+) diff --git a/transformation-config/docs.yaml b/transformation-config/docs.yaml index 1ca6752d..4e29e14e 100644 --- a/transformation-config/docs.yaml +++ b/transformation-config/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/transformation-config/skills/audit-3000/config.yaml b/transformation-config/skills/audit-3000/config.yaml index 99252ec6..9ba87386 100644 --- a/transformation-config/skills/audit-3000/config.yaml +++ b/transformation-config/skills/audit-3000/config.yaml @@ -6,6 +6,7 @@ references: preamble: "**Read ONLY this file.** Do not read any other reference file until this one tells you to." shared_docs: - https://posthog.com/docs/getting-started/identify-users.md + - https://posthog.com/docs/product-analytics/identity-resolution.md - https://posthog.com/docs/product-analytics/best-practices.md - https://posthog.com/docs/session-replay/how-to-control-which-sessions-you-record.md - https://posthog.com/docs/session-replay/network-recording.md diff --git a/transformation-config/skills/audit-identify/config.yaml b/transformation-config/skills/audit-identify/config.yaml index 60ab37c3..56065f20 100644 --- a/transformation-config/skills/audit-identify/config.yaml +++ b/transformation-config/skills/audit-identify/config.yaml @@ -6,6 +6,7 @@ references: preamble: "**Read ONLY this file.** Do not read any other reference file until this one tells you to." shared_docs: - https://posthog.com/docs/getting-started/identify-users.md + - https://posthog.com/docs/product-analytics/identity-resolution.md - https://posthog.com/docs/product-analytics/cutting-costs.md - https://posthog.com/docs/libraries/js/config.md variants: diff --git a/transformation-config/skills/audit/config.yaml b/transformation-config/skills/audit/config.yaml index 0dd7276c..3d1dd7e9 100644 --- a/transformation-config/skills/audit/config.yaml +++ b/transformation-config/skills/audit/config.yaml @@ -6,6 +6,7 @@ references: preamble: "**Read ONLY this file.** Do not read any other reference file until this one tells you to." shared_docs: - https://posthog.com/docs/getting-started/identify-users.md + - https://posthog.com/docs/product-analytics/identity-resolution.md - https://posthog.com/docs/product-analytics/best-practices.md variants: - id: all diff --git a/transformation-config/skills/events-audit/config.yaml b/transformation-config/skills/events-audit/config.yaml index 12e462f8..78f2c0ad 100644 --- a/transformation-config/skills/events-audit/config.yaml +++ b/transformation-config/skills/events-audit/config.yaml @@ -7,6 +7,7 @@ references: shared_docs: - https://posthog.com/docs/product-analytics/best-practices.md - https://posthog.com/docs/getting-started/identify-users.md + - https://posthog.com/docs/product-analytics/identity-resolution.md variants: - id: all display_name: PostHog events audit diff --git a/transformation-config/skills/identify/config.yaml b/transformation-config/skills/identify/config.yaml index ed046697..f257eeb4 100644 --- a/transformation-config/skills/identify/config.yaml +++ b/transformation-config/skills/identify/config.yaml @@ -8,3 +8,4 @@ variants: 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/transformation-config/skills/integration/config.yaml b/transformation-config/skills/integration/config.yaml index 56949f1a..3542ab9b 100644 --- a/transformation-config/skills/integration/config.yaml +++ b/transformation-config/skills/integration/config.yaml @@ -4,6 +4,7 @@ template: description.md description: PostHog integration for {display_name} applications shared_docs: - https://posthog.com/docs/getting-started/identify-users.md + - https://posthog.com/docs/product-analytics/identity-resolution.md variants: - id: nextjs-app-router example_paths: basics/next-app-router diff --git a/transformation-config/skills/omnibus/instrument-integration/config.yaml b/transformation-config/skills/omnibus/instrument-integration/config.yaml index e7b2cf9b..a6fb38ea 100644 --- a/transformation-config/skills/omnibus/instrument-integration/config.yaml +++ b/transformation-config/skills/omnibus/instrument-integration/config.yaml @@ -5,6 +5,7 @@ description: Add PostHog SDK integration to your application. Use when setting u tags: [] shared_docs: - https://posthog.com/docs/getting-started/identify-users.md + - https://posthog.com/docs/product-analytics/identity-resolution.md variants: - id: all display_name: all supported frameworks diff --git a/transformation-config/skills/omnibus/instrument-product-analytics/config.yaml b/transformation-config/skills/omnibus/instrument-product-analytics/config.yaml index fd7efd27..0869ab73 100644 --- a/transformation-config/skills/omnibus/instrument-product-analytics/config.yaml +++ b/transformation-config/skills/omnibus/instrument-product-analytics/config.yaml @@ -6,6 +6,7 @@ description: Add PostHog product analytics events to track user behavior. Use af tags: [] shared_docs: - https://posthog.com/docs/getting-started/identify-users.md + - https://posthog.com/docs/product-analytics/identity-resolution.md variants: - id: all display_name: all supported frameworks diff --git a/transformation-config/skills/posthog-best-practices/config.yaml b/transformation-config/skills/posthog-best-practices/config.yaml index 8e5cb040..c3894c26 100644 --- a/transformation-config/skills/posthog-best-practices/config.yaml +++ b/transformation-config/skills/posthog-best-practices/config.yaml @@ -4,6 +4,7 @@ description: Framework-agnostic, distilled best practices for using PostHog tags: [best-practices] shared_docs: - https://posthog.com/docs/getting-started/identify-users.md + - https://posthog.com/docs/product-analytics/identity-resolution.md - https://posthog.com/docs/new-to-posthog/understand-posthog.md - https://posthog.com/docs/privacy/data-collection.md - https://posthog.com/docs/advanced/proxy.md diff --git a/transformation-config/skills/revenue-analytics/config.yaml b/transformation-config/skills/revenue-analytics/config.yaml index 212520a1..889e1fca 100644 --- a/transformation-config/skills/revenue-analytics/config.yaml +++ b/transformation-config/skills/revenue-analytics/config.yaml @@ -6,6 +6,7 @@ tags: [revenue-analytics, stripe] shared_docs: - https://posthog.com/docs/revenue-analytics/connect-to-customers.md - https://posthog.com/docs/getting-started/identify-users.md + - https://posthog.com/docs/product-analytics/identity-resolution.md variants: - id: setup display_name: Stripe Revenue Analytics From 5d937f57592a18fda10093f57e3bde5d9e0bb783 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 16 Jun 2026 22:26:29 -0400 Subject: [PATCH 13/38] build skill: leave pre-existing errors in untouched files alone The build agent was re-running typecheck/lint in a loop chasing a green it could never reach, because the test app had pre-existing type errors in files the integration never touched. Make ownership explicit: only fix errors in files this integration changed; a failure in an untouched file is pre-existing, note it and move on. Don't re-run hoping it clears. Co-Authored-By: Claude Fable 5 --- transformation-config/skills/build/description.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/transformation-config/skills/build/description.md b/transformation-config/skills/build/description.md index 208f295b..aa9356cf 100644 --- a/transformation-config/skills/build/description.md +++ b/transformation-config/skills/build/description.md @@ -14,8 +14,11 @@ 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). Fix only obvious issues from the new PostHog code — -a missing import, a wrong call shape. +(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 From 46e04e7eb509c593b81e92481b03428e1d33703c Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Thu, 18 Jun 2026 09:15:22 -0400 Subject: [PATCH 14/38] fix: drop stale identity-resolution shared_doc to match main The branch carried an identity-resolution shared_doc that main removed; the merge kept the old version, adding the doc to ~43 built skills. Align the 8 configs with main so the build output drifts only where the agents content type is added. Co-Authored-By: Claude Opus 4.8 --- context/skills/audit-identify/config.yaml | 1 - context/skills/audit/config.yaml | 1 - context/skills/events-audit/config.yaml | 1 - context/skills/integration/config.yaml | 1 - context/skills/omnibus/instrument-integration/config.yaml | 1 - context/skills/omnibus/instrument-product-analytics/config.yaml | 1 - context/skills/posthog-best-practices/config.yaml | 1 - context/skills/revenue-analytics/config.yaml | 1 - 8 files changed, 8 deletions(-) diff --git a/context/skills/audit-identify/config.yaml b/context/skills/audit-identify/config.yaml index df4bcfd3..66c30f9d 100644 --- a/context/skills/audit-identify/config.yaml +++ b/context/skills/audit-identify/config.yaml @@ -10,7 +10,6 @@ references: preamble: "**Read ONLY this file.** Do not read any other reference file until this one tells you to." shared_docs: - https://posthog.com/docs/getting-started/identify-users.md - - https://posthog.com/docs/product-analytics/identity-resolution.md - https://posthog.com/docs/product-analytics/cutting-costs.md - https://posthog.com/docs/libraries/js/config.md variants: diff --git a/context/skills/audit/config.yaml b/context/skills/audit/config.yaml index d378b9a9..45a7cb42 100644 --- a/context/skills/audit/config.yaml +++ b/context/skills/audit/config.yaml @@ -11,7 +11,6 @@ references: preamble: "**Read ONLY this file.** Do not read any other reference file until this one tells you to." shared_docs: - https://posthog.com/docs/getting-started/identify-users.md - - https://posthog.com/docs/product-analytics/identity-resolution.md - https://posthog.com/docs/product-analytics/best-practices.md variants: - id: all diff --git a/context/skills/events-audit/config.yaml b/context/skills/events-audit/config.yaml index b8c494ca..e0a90291 100644 --- a/context/skills/events-audit/config.yaml +++ b/context/skills/events-audit/config.yaml @@ -7,7 +7,6 @@ references: shared_docs: - https://posthog.com/docs/product-analytics/best-practices.md - https://posthog.com/docs/getting-started/identify-users.md - - https://posthog.com/docs/product-analytics/identity-resolution.md variants: - id: all display_name: PostHog events audit diff --git a/context/skills/integration/config.yaml b/context/skills/integration/config.yaml index 932c4573..2fbc119d 100644 --- a/context/skills/integration/config.yaml +++ b/context/skills/integration/config.yaml @@ -4,7 +4,6 @@ template: description.md description: PostHog integration for {display_name} applications shared_docs: - https://posthog.com/docs/getting-started/identify-users.md - - https://posthog.com/docs/product-analytics/identity-resolution.md variants: - id: nextjs-app-router example_paths: example-apps/next-app-router diff --git a/context/skills/omnibus/instrument-integration/config.yaml b/context/skills/omnibus/instrument-integration/config.yaml index 288cc811..b2d1ce82 100644 --- a/context/skills/omnibus/instrument-integration/config.yaml +++ b/context/skills/omnibus/instrument-integration/config.yaml @@ -5,7 +5,6 @@ description: Add PostHog SDK integration to your application. Use when setting u tags: [] shared_docs: - https://posthog.com/docs/getting-started/identify-users.md - - https://posthog.com/docs/product-analytics/identity-resolution.md variants: - id: all display_name: all supported frameworks diff --git a/context/skills/omnibus/instrument-product-analytics/config.yaml b/context/skills/omnibus/instrument-product-analytics/config.yaml index f46ce0bb..a998e9ce 100644 --- a/context/skills/omnibus/instrument-product-analytics/config.yaml +++ b/context/skills/omnibus/instrument-product-analytics/config.yaml @@ -6,7 +6,6 @@ description: Add PostHog product analytics events to track user behavior. Use af tags: [] shared_docs: - https://posthog.com/docs/getting-started/identify-users.md - - https://posthog.com/docs/product-analytics/identity-resolution.md variants: - id: all display_name: all supported frameworks diff --git a/context/skills/posthog-best-practices/config.yaml b/context/skills/posthog-best-practices/config.yaml index 3d8e4ba3..4fe8fa58 100644 --- a/context/skills/posthog-best-practices/config.yaml +++ b/context/skills/posthog-best-practices/config.yaml @@ -4,7 +4,6 @@ description: Framework-agnostic, distilled best practices for using PostHog tags: [best-practices] shared_docs: - https://posthog.com/docs/getting-started/identify-users.md - - https://posthog.com/docs/product-analytics/identity-resolution.md - https://posthog.com/docs/new-to-posthog/understand-posthog.md - https://posthog.com/docs/privacy/data-collection.md - https://posthog.com/docs/advanced/proxy.md diff --git a/context/skills/revenue-analytics/config.yaml b/context/skills/revenue-analytics/config.yaml index fd041804..1a595620 100644 --- a/context/skills/revenue-analytics/config.yaml +++ b/context/skills/revenue-analytics/config.yaml @@ -9,7 +9,6 @@ cli: shared_docs: - https://posthog.com/docs/revenue-analytics/connect-to-customers.md - https://posthog.com/docs/getting-started/identify-users.md - - https://posthog.com/docs/product-analytics/identity-resolution.md variants: - id: setup display_name: Stripe Revenue Analytics From 1744e83ac5fdc15bb676f4f35e702d83bbc03a1c Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Thu, 18 Jun 2026 09:24:40 -0400 Subject: [PATCH 15/38] refactor: nest orchestrator step-skills under basic-integration/, drop stray file - move the 8 per-task step skills (build, capture, dashboard, error-tracking-step, identify, init, install, report) under skills/basic-integration/ so they stop polluting the top-level skills namespace; IDs become basic-integration- (path-based, like omnibus-*) - update the agent prompts skills: refs to the new IDs - delete the stray orchestrator-ci-plan.md committed by accident Co-Authored-By: Claude Opus 4.8 --- context/agents/build.md | 2 +- context/agents/capture.md | 2 +- context/agents/dashboard.md | 2 +- context/agents/error-tracking.md | 2 +- context/agents/identify.md | 2 +- context/agents/init.md | 2 +- context/agents/install.md | 2 +- context/agents/report.md | 2 +- .../{ => basic-integration}/build/config.yaml | 0 .../build/description.md | 0 .../capture/config.yaml | 0 .../capture/description.md | 0 .../dashboard/config.yaml | 0 .../dashboard/description.md | 0 .../error-tracking-step/config.yaml | 0 .../error-tracking-step/description.md | 0 .../identify/config.yaml | 0 .../identify/description.md | 0 .../{ => basic-integration}/init/config.yaml | 0 .../init/description.md | 0 .../install/config.yaml | 0 .../install/description.md | 0 .../report/config.yaml | 0 .../report/description.md | 0 orchestrator-ci-plan.md | 210 ------------------ 25 files changed, 8 insertions(+), 218 deletions(-) rename context/skills/{ => basic-integration}/build/config.yaml (100%) rename context/skills/{ => basic-integration}/build/description.md (100%) rename context/skills/{ => basic-integration}/capture/config.yaml (100%) rename context/skills/{ => basic-integration}/capture/description.md (100%) rename context/skills/{ => basic-integration}/dashboard/config.yaml (100%) rename context/skills/{ => basic-integration}/dashboard/description.md (100%) rename context/skills/{ => basic-integration}/error-tracking-step/config.yaml (100%) rename context/skills/{ => basic-integration}/error-tracking-step/description.md (100%) rename context/skills/{ => basic-integration}/identify/config.yaml (100%) rename context/skills/{ => basic-integration}/identify/description.md (100%) rename context/skills/{ => basic-integration}/init/config.yaml (100%) rename context/skills/{ => basic-integration}/init/description.md (100%) rename context/skills/{ => basic-integration}/install/config.yaml (100%) rename context/skills/{ => basic-integration}/install/description.md (100%) rename context/skills/{ => basic-integration}/report/config.yaml (100%) rename context/skills/{ => basic-integration}/report/description.md (100%) delete mode 100644 orchestrator-ci-plan.md diff --git a/context/agents/build.md b/context/agents/build.md index e4c97add..77243bab 100644 --- a/context/agents/build.md +++ b/context/agents/build.md @@ -3,7 +3,7 @@ type: build flow: posthog-integration label: Install dependencies and build model: claude-sonnet-4-6 -skills: [build] +skills: [basic-integration-build] allowedTools: [Read, Edit, Glob, Grep, Bash] disallowedTools: [enqueue_task] dependsOn: [install, init, identify, error-tracking, capture] diff --git a/context/agents/capture.md b/context/agents/capture.md index 08b0cfcf..c2501897 100644 --- a/context/agents/capture.md +++ b/context/agents/capture.md @@ -3,7 +3,7 @@ type: capture flow: posthog-integration label: Capture events model: claude-sonnet-4-6 -skills: [capture] +skills: [basic-integration-capture] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [install, init] diff --git a/context/agents/dashboard.md b/context/agents/dashboard.md index 7dcb0745..54c336de 100644 --- a/context/agents/dashboard.md +++ b/context/agents/dashboard.md @@ -3,7 +3,7 @@ type: dashboard flow: posthog-integration label: Create a starter dashboard model: claude-sonnet-4-6 -skills: [dashboard] +skills: [basic-integration-dashboard] allowedTools: [Read, Glob, Grep] disallowedTools: [Write, Edit, Bash, enqueue_task] dependsOn: [build] diff --git a/context/agents/error-tracking.md b/context/agents/error-tracking.md index c3489c07..c7e2aea3 100644 --- a/context/agents/error-tracking.md +++ b/context/agents/error-tracking.md @@ -3,7 +3,7 @@ type: error-tracking flow: posthog-integration label: Add error tracking model: claude-sonnet-4-6 -skills: [error-tracking-step] +skills: [basic-integration-error-tracking-step] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [install, init] diff --git a/context/agents/identify.md b/context/agents/identify.md index 70f8ecad..658afca9 100644 --- a/context/agents/identify.md +++ b/context/agents/identify.md @@ -3,7 +3,7 @@ type: identify flow: posthog-integration label: Wire user identification model: claude-sonnet-4-6 -skills: [identify] +skills: [basic-integration-identify] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [install, init] diff --git a/context/agents/init.md b/context/agents/init.md index 052b87fc..ffc62c2d 100644 --- a/context/agents/init.md +++ b/context/agents/init.md @@ -3,7 +3,7 @@ type: init flow: posthog-integration label: Set up PostHog initialization model: claude-haiku-4-5-20251001 -skills: [init] +skills: [basic-integration-init] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [] diff --git a/context/agents/install.md b/context/agents/install.md index e11fa69d..4ed83e18 100644 --- a/context/agents/install.md +++ b/context/agents/install.md @@ -3,7 +3,7 @@ type: install flow: posthog-integration label: Add the PostHog SDK to the manifest model: claude-haiku-4-5-20251001 -skills: [install] +skills: [basic-integration-install] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [] diff --git a/context/agents/report.md b/context/agents/report.md index ed0c6747..1e7f126e 100644 --- a/context/agents/report.md +++ b/context/agents/report.md @@ -3,7 +3,7 @@ type: report flow: posthog-integration label: Write the setup report model: claude-sonnet-4-6 -skills: [report] +skills: [basic-integration-report] allowedTools: [Read, Write, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [dashboard] diff --git a/context/skills/build/config.yaml b/context/skills/basic-integration/build/config.yaml similarity index 100% rename from context/skills/build/config.yaml rename to context/skills/basic-integration/build/config.yaml diff --git a/context/skills/build/description.md b/context/skills/basic-integration/build/description.md similarity index 100% rename from context/skills/build/description.md rename to context/skills/basic-integration/build/description.md diff --git a/context/skills/capture/config.yaml b/context/skills/basic-integration/capture/config.yaml similarity index 100% rename from context/skills/capture/config.yaml rename to context/skills/basic-integration/capture/config.yaml diff --git a/context/skills/capture/description.md b/context/skills/basic-integration/capture/description.md similarity index 100% rename from context/skills/capture/description.md rename to context/skills/basic-integration/capture/description.md diff --git a/context/skills/dashboard/config.yaml b/context/skills/basic-integration/dashboard/config.yaml similarity index 100% rename from context/skills/dashboard/config.yaml rename to context/skills/basic-integration/dashboard/config.yaml diff --git a/context/skills/dashboard/description.md b/context/skills/basic-integration/dashboard/description.md similarity index 100% rename from context/skills/dashboard/description.md rename to context/skills/basic-integration/dashboard/description.md diff --git a/context/skills/error-tracking-step/config.yaml b/context/skills/basic-integration/error-tracking-step/config.yaml similarity index 100% rename from context/skills/error-tracking-step/config.yaml rename to context/skills/basic-integration/error-tracking-step/config.yaml diff --git a/context/skills/error-tracking-step/description.md b/context/skills/basic-integration/error-tracking-step/description.md similarity index 100% rename from context/skills/error-tracking-step/description.md rename to context/skills/basic-integration/error-tracking-step/description.md diff --git a/context/skills/identify/config.yaml b/context/skills/basic-integration/identify/config.yaml similarity index 100% rename from context/skills/identify/config.yaml rename to context/skills/basic-integration/identify/config.yaml diff --git a/context/skills/identify/description.md b/context/skills/basic-integration/identify/description.md similarity index 100% rename from context/skills/identify/description.md rename to context/skills/basic-integration/identify/description.md diff --git a/context/skills/init/config.yaml b/context/skills/basic-integration/init/config.yaml similarity index 100% rename from context/skills/init/config.yaml rename to context/skills/basic-integration/init/config.yaml diff --git a/context/skills/init/description.md b/context/skills/basic-integration/init/description.md similarity index 100% rename from context/skills/init/description.md rename to context/skills/basic-integration/init/description.md diff --git a/context/skills/install/config.yaml b/context/skills/basic-integration/install/config.yaml similarity index 100% rename from context/skills/install/config.yaml rename to context/skills/basic-integration/install/config.yaml diff --git a/context/skills/install/description.md b/context/skills/basic-integration/install/description.md similarity index 100% rename from context/skills/install/description.md rename to context/skills/basic-integration/install/description.md diff --git a/context/skills/report/config.yaml b/context/skills/basic-integration/report/config.yaml similarity index 100% rename from context/skills/report/config.yaml rename to context/skills/basic-integration/report/config.yaml diff --git a/context/skills/report/description.md b/context/skills/basic-integration/report/description.md similarity index 100% rename from context/skills/report/description.md rename to context/skills/basic-integration/report/description.md diff --git a/orchestrator-ci-plan.md b/orchestrator-ci-plan.md deleted file mode 100644 index f33f2069..00000000 --- a/orchestrator-ci-plan.md +++ /dev/null @@ -1,210 +0,0 @@ -# Running the orchestrator end-to-end in CI - -## 1. How Wizard CI works - -The trigger lives in the wizard repo: -`wizard-orchestrator/.github/workflows/wizard-ci-trigger.yml` - -A PR comment `/wizard-ci ` fires `handle-command`, which calls -`POST /repos/PostHog/wizard-workbench/dispatches` with event type -`wizard-ci-trigger` and a `client_payload` containing: - -``` -app, wizard_ref, context_mill_ref, notify_pr: true, source_pr_number, ... -``` - -The workbench workflow `wizard-workbench/.github/workflows/wizard-ci.yml` picks -that up, clones and builds wizard + context-mill + MCP in `setup-wizard-deps`, -starts both servers in the background, then runs: - -```bash -pnpm wizard-ci --app "$MATRIX_APP" --base "$INPUT_BASE_BRANCH" [--trigger-id ...] [--evaluate] -``` - -Inside `wizard-ci` (`services/wizard-ci/index.ts`), `runWizard` spawns: - -```bash -node dist/bin.js --local-mcp --ci --region us --api-key --install-dir -``` - -`--local-mcp` tells the wizard to use `http://localhost:8765` (context-mill dev -server) instead of the GitHub releases URL for both skills and agent prompts. - -Auth: `POSTHOG_PERSONAL_API_KEY` is the CI bot's PostHog API key (secret -`GH_APP_POSTHOG_WIZARD_CI_BOT_POSTHOG_PERSONAL_KEY`); the wizard uses it for -`--api-key` and the MCP server gets it the same way. - ---- - -## 2. The flag-override path end-to-end - -**Step 1 — CI build.** -`setup-wizard-deps/action.yml` (line ~101) runs `pnpm build:ci`, which inlines -`NODE_ENV=ci` into the bundle. That is the guard inside -`applyCiFlagOverrides` (`src/utils/ci-flag-overrides.ts` line 25): - -```ts -if (process.env.NODE_ENV === 'production') return flags; -``` - -Published packages inline `"production"` and the function becomes a no-op. -CI builds do not, so the function is live. - -**Step 2 — env var.** -`applyCiFlagOverrides` reads `runtimeEnv('WIZARD_CI_FLAG_OVERRIDES')` at -runtime (registered in `src/env.ts` line 45). It expects a JSON object: -`{"flag-key": value, ...}`. A malformed value throws and kills the run. - -**Step 3 — flag eval.** -`getAllFlagsForWizard` in `src/utils/analytics.ts` (line 211) fetches live -flags from PostHog, then unconditionally calls `applyCiFlagOverrides` over -the result (line 241) and caches the merged map. The override wins because it -runs after the network fetch. - -**Step 4 — orchestrator gate.** -`isOrchestratorEnabled` in `src/lib/agent/agent-interface.ts` (line 262) -reads `flags['wizard-orchestrator'] === 'true'`. When the override is in the -map, the orchestrator branch fires in `runProgram` regardless of what the live -flag says. - -**Does the current CI workflow expose WIZARD_CI_FLAG_OVERRIDES?** - -No. Neither `wizard-ci.yml` nor `setup-wizard-deps/action.yml` pass -`WIZARD_CI_FLAG_OVERRIDES` into the `Execute wizard` step. The env block of -that step (`wizard-ci.yml` lines 634–650) does not mention it. - ---- - -## 3. What runs (and doesn't) in CI for the orchestrator - -**CI-excluded task types.** -`ciExcludedTaskTypes()` (`src/utils/ci-flag-overrides.ts` line 56) reads -`WIZARD_CI_EXCLUDE_TASKS` (a comma-separated list). The orchestrator runner -(`src/lib/programs/orchestrator/orchestrator-runner.ts` line 93) passes -`{ exclude: ciExcludedTaskTypes() }` to `loadAgentRegistry`. The registry -then drops those types so the seed agent cannot enqueue them. - -PR #639 / commit `0a62554` in context-mill says "dashboard is not a CI task". -The `dashboard.md` agent (`transformation-config/agents/dashboard.md`) has no -`ci: false` frontmatter — the exclusion is entirely harness-side via -`WIZARD_CI_EXCLUDE_TASKS=dashboard`. That env var also needs to be set by the -CI workflow (currently missing from the `Execute wizard` env block). - -**Agent prompts — the AGENTS_BASE_URL gap.** -`setup-wizard-deps/action.yml` runs `npm run build` for context-mill (line 158) -without setting `AGENTS_BASE_URL`. Inside `scripts/lib/agent-generator.js` -(line 41), `buildAgents` falls back to `DEFAULT_AGENTS_BASE_URL`: - -``` -https://github.com/PostHog/context-mill/releases/latest/download/agents -``` - -That URL points to production releases, not to the local dev server. When -context-mill then starts (`npm run dev`) it regenerates `agent-menu.json` with -`http://localhost:8765/agents/…` URLs. But the action only runs `npm run build` -then exports `CONTEXT_MILL_PATH`. The dev server is started later in the -`Run Wizard CI` step via `npm run dev &`. At that point the dev server sets -`AGENTS_BASE_URL = http://localhost:8765/agents` internally (dev-server.js -lines 65–66) and rebuilds, so the in-memory menu is correct. - -In practice `--local-mcp` makes the wizard call `http://localhost:8765/agent-menu.json`, -which the running dev server serves with correct localhost URLs — so the agents -are fetched correctly as long as `npm run dev` is running. The skill-menu has -the same pattern. The memory note "must set BOTH SKILLS_BASE_URL + AGENTS_BASE_URL" -applies to manual standalone `npm run build` invocations; CI is fine because it -always goes through the dev server. - -**What actually runs.** -All task types in `dist/agents/` are eligible except those in -`WIZARD_CI_EXCLUDE_TASKS`. Currently that env var is never set in CI, so the -seed agent would try to enqueue `dashboard` — which requires MCP write access to -create a PostHog dashboard. Whether that succeeds depends on the CI bot's -PostHog permissions, but it is undesirable for a fast CI loop. - ---- - -## 4. The gap: no way to pass flag overrides via a PR comment - -The trigger command `wizard-ci-trigger.yml` accepts only: - -``` -/wizard-ci -``` - -It dispatches a fixed `client_payload` with no `flag_overrides` or -`ci_flag_overrides` field. The workbench `wizard-ci.yml` `resolve-inputs` step -does not read any such field from `client_payload`. There is no path from a PR -comment to `WIZARD_CI_FLAG_OVERRIDES` in the execute-wizard env. - ---- - -## 5. Concrete recommendation - -### Option A — add flag-override plumbing (recommended, ~1 day) - -Two files need changes. - -**wizard-workbench/.github/workflows/wizard-ci.yml** - -1. Add `flag_overrides` to `workflow_dispatch` inputs (type: string, default: ''). -2. In `resolve-inputs`: read `CP_FLAG_OVERRIDES` / `INPUT_FLAG_OVERRIDES` and - emit `flag_overrides` output (same pattern as the other inputs). -3. Pass it as `input_flag_overrides` through `discover` outputs. -4. In the `Execute wizard` env block (line 634), add: - ```yaml - WIZARD_CI_FLAG_OVERRIDES: ${{ needs.discover.outputs.input_flag_overrides }} - WIZARD_CI_EXCLUDE_TASKS: dashboard - ``` - -**wizard-orchestrator/.github/workflows/wizard-ci-trigger.yml** - -In `handle-command`, add `flag_overrides` to the `client_payload`: -```js -const overridesMatch = comment.match(/--flags\s+(\S+)/); -flag_overrides: overridesMatch ? overridesMatch[1] : '' -``` - -This lets a PR comment like: -``` -/wizard-ci basic-integration/next-js/15-app-router-saas --flags {"wizard-orchestrator":true} -``` -route `WIZARD_CI_FLAG_OVERRIDES={"wizard-orchestrator":true}` into the wizard binary. - -### Option B — trigger via workflow_dispatch now (no code change needed) - -Go to `wizard-workbench` → Actions → "Wizard CI" → Run workflow, and set: -- `app`: e.g. `basic-integration/next-js/15-app-router-saas` -- `wizard_ref`: `experiment/orchestrator-run-cache` -- `context_mill_ref`: `experiment/orchestrator` - -Then add `WIZARD_CI_FLAG_OVERRIDES` and `WIZARD_CI_EXCLUDE_TASKS` as manual -additions to the env block — but since the current workflow has no `flag_overrides` -input, you can't pass it this way without editing the yaml first. - -**Short-term workaround (no workflow edits):** add a temporary `env:` override -directly in the `Execute wizard` step of `wizard-ci.yml` on a branch: - -```yaml -WIZARD_CI_FLAG_OVERRIDES: '{"wizard-orchestrator":true}' -WIZARD_CI_EXCLUDE_TASKS: dashboard -``` - -Then trigger CI via workflow_dispatch with `wizard_ref: experiment/orchestrator-run-cache` -and `context_mill_ref: experiment/orchestrator`. That is a single-line change, safe -to push to a short-lived branch of wizard-workbench without merging. - ---- - -## Summary of env vars needed in the Execute wizard step - -| Var | Value | Status | -|-----|-------|--------| -| `WIZARD_CI_FLAG_OVERRIDES` | `{"wizard-orchestrator":true}` | **missing** | -| `WIZARD_CI_EXCLUDE_TASKS` | `dashboard` | **missing** | -| `POSTHOG_PERSONAL_API_KEY` | bot secret | already wired | -| `WIZARD_PATH` | `~/wizard` | already wired | -| `CONTEXT_MILL_PATH` | `~/context-mill` | already wired | -| `MCP_PATH` | `~/posthog/services/mcp` | already wired | - -The two missing vars are the only change needed to make the orchestrator path -run end-to-end in CI. From a16ed9b3939fe75164eb4846a2f840dbc23ed402 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Thu, 18 Jun 2026 11:30:07 -0400 Subject: [PATCH 16/38] fix(orchestrator): keep basic-integration step-skills goal-oriented MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The step-skills baked JS/Node specifics into every framework's run. Strip the JS-pinned docs_urls from the install, init, capture, and error-tracking configs, and de-hardcode the identify and capture prose, so SDK specifics come from the per-framework reference, not the step. lower_snake_case and the correlation header names stay — stable conventions, not framework specifics. Recover the universal monolith guidance the steps were missing: the analytics contract and scan-first in capture, error capture at natural boundaries, and a before-you-merge checklist in the report. Move the event plan to .posthog-wizard-cache/.posthog-events.json so it is run scaffolding, cleaned up with the rest, not left in the project. Co-Authored-By: Claude Opus 4.8 --- context/agents/capture.md | 4 +-- context/agents/report.md | 3 +- .../basic-integration/capture/config.yaml | 3 +- .../basic-integration/capture/description.md | 34 +++++++++++-------- .../error-tracking-step/config.yaml | 3 -- .../error-tracking-step/description.md | 10 +++--- .../basic-integration/identify/description.md | 14 +++++--- .../skills/basic-integration/init/config.yaml | 3 -- .../basic-integration/init/description.md | 4 --- .../basic-integration/install/config.yaml | 3 -- .../basic-integration/install/description.md | 4 --- .../basic-integration/report/description.md | 14 ++++++-- 12 files changed, 52 insertions(+), 47 deletions(-) diff --git a/context/agents/capture.md b/context/agents/capture.md index c2501897..db5a77c4 100644 --- a/context/agents/capture.md +++ b/context/agents/capture.md @@ -18,5 +18,5 @@ 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-events.json` lists the events you -instrumented. +real action, not on page load, and `.posthog-wizard-cache/.posthog-events.json` +lists the events you instrumented. diff --git a/context/agents/report.md b/context/agents/report.md index 1e7f126e..d9db8a69 100644 --- a/context/agents/report.md +++ b/context/agents/report.md @@ -12,7 +12,8 @@ dependsOn: [dashboard] ## Goal Write the setup report summarizing what this integration did, drawing only on the -run's queue log (`.posthog-wizard-cache/`) and the local `.posthog-events.json`. +run's queue log and event plan in `.posthog-wizard-cache/` (`queue.json` and +`.posthog-events.json`). ## How you know you succeeded diff --git a/context/skills/basic-integration/capture/config.yaml b/context/skills/basic-integration/capture/config.yaml index 8f973906..98e99d55 100644 --- a/context/skills/basic-integration/capture/config.yaml +++ b/context/skills/basic-integration/capture/config.yaml @@ -1,11 +1,10 @@ type: docs-only template: description.md -description: Instrument the planned events with posthog.capture +description: Instrument the planned events with PostHog capture calls tags: [orchestrator, capture] variants: - id: all display_name: PostHog capture step tags: [orchestrator, capture] docs_urls: - - https://posthog.com/docs/libraries/js.md - https://posthog.com/docs/product-analytics/best-practices.md diff --git a/context/skills/basic-integration/capture/description.md b/context/skills/basic-integration/capture/description.md index 67a394d4..b0a7d1b7 100644 --- a/context/skills/basic-integration/capture/description.md +++ b/context/skills/basic-integration/capture/description.md @@ -7,29 +7,35 @@ pass, reading each file once. 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). Don't duplicate events that -already exist. Server-side events are required if there is instrumentable -server-side code (API routes, server actions): payment/checkout completion, -webhook handlers, and auth endpoints. - -Write the chosen events to `.posthog-events.json` at the project root — a JSON -array of `{ event, description, file }`, one entry per event. Write it before you -start editing: it drives the event-plan view, and it is the source the report -reads later. +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 add `posthog.capture('event_name', { ...props })` 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. +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-events.json` in place for the report. +Leave `.posthog-wizard-cache/.posthog-events.json` in place for the report. ## Reference diff --git a/context/skills/basic-integration/error-tracking-step/config.yaml b/context/skills/basic-integration/error-tracking-step/config.yaml index ec9aea97..0d050f96 100644 --- a/context/skills/basic-integration/error-tracking-step/config.yaml +++ b/context/skills/basic-integration/error-tracking-step/config.yaml @@ -6,6 +6,3 @@ variants: - id: all display_name: PostHog error-tracking step tags: [orchestrator, error-tracking] - docs_urls: - - https://posthog.com/docs/error-tracking/installation/web.md - - https://posthog.com/docs/error-tracking/installation/node.md diff --git a/context/skills/basic-integration/error-tracking-step/description.md b/context/skills/basic-integration/error-tracking-step/description.md index 2670a024..b2b5b91f 100644 --- a/context/skills/basic-integration/error-tracking-step/description.md +++ b/context/skills/basic-integration/error-tracking-step/description.md @@ -5,9 +5,9 @@ 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, and you are done. One handler is enough — do not read -through the whole app or wrap individual components or routes by hand. +add the handler there. Do not read through the whole app or wrap individual +components or routes by hand. -## Reference - -{references} +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. diff --git a/context/skills/basic-integration/identify/description.md b/context/skills/basic-integration/identify/description.md index 8b4240c2..c5a002bc 100644 --- a/context/skills/basic-integration/identify/description.md +++ b/context/skills/basic-integration/identify/description.md @@ -1,16 +1,22 @@ # Identify users -Call `posthog.identify` at the moment the app learns who the user is — typically -on login and signup success. +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. -- Pass useful person properties (email, name, plan) as the second argument. -- Call `posthog.reset()` on logout so the next user starts clean. +- 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 index 0317ac8e..2100b785 100644 --- a/context/skills/basic-integration/init/config.yaml +++ b/context/skills/basic-integration/init/config.yaml @@ -6,6 +6,3 @@ variants: - id: all display_name: PostHog init step tags: [orchestrator, init] - docs_urls: - - https://posthog.com/docs/libraries/js.md - - https://posthog.com/docs/libraries/node.md diff --git a/context/skills/basic-integration/init/description.md b/context/skills/basic-integration/init/description.md index 2440423e..b550d169 100644 --- a/context/skills/basic-integration/init/description.md +++ b/context/skills/basic-integration/init/description.md @@ -16,7 +16,3 @@ 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 index a442772b..0bb3fd1d 100644 --- a/context/skills/basic-integration/install/config.yaml +++ b/context/skills/basic-integration/install/config.yaml @@ -6,6 +6,3 @@ variants: - id: all display_name: PostHog install step tags: [orchestrator, install] - docs_urls: - - https://posthog.com/docs/libraries/js.md - - https://posthog.com/docs/libraries/node.md diff --git a/context/skills/basic-integration/install/description.md b/context/skills/basic-integration/install/description.md index f914b263..cb6bdb9b 100644 --- a/context/skills/basic-integration/install/description.md +++ b/context/skills/basic-integration/install/description.md @@ -12,7 +12,3 @@ 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/description.md b/context/skills/basic-integration/report/description.md index 4cc554ed..186303d7 100644 --- a/context/skills/basic-integration/report/description.md +++ b/context/skills/basic-integration/report/description.md @@ -6,18 +6,28 @@ 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-events.json` — the events that were instrumented. +- `.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-events.json`). + (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. From 4d4a682cd51f53a2da9568058557c577799c4cd5 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Thu, 18 Jun 2026 13:51:48 -0400 Subject: [PATCH 17/38] feat(orchestrator): per-framework variants for the SDK-divergent step-skills MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Install, init, capture, and error-tracking each carry framework-specific work, so mirror the integration skill's 36 variants onto them: each variant packages that framework's docs page (duplicated across steps for now). The step prose stays generic; the variant supplies the framework HOW. Generic steps (identify, report, dashboard, build) stay single-variant. Reverses the docs_urls strip from the previous commit — the per-framework pages return as variants rather than inline JS-only docs. Co-Authored-By: Claude Opus 4.8 --- .../basic-integration/capture/config.yaml | 383 +++++++++++++++++- .../error-tracking-step/config.yaml | 381 ++++++++++++++++- .../error-tracking-step/description.md | 4 + .../skills/basic-integration/init/config.yaml | 381 ++++++++++++++++- .../basic-integration/init/description.md | 4 + .../basic-integration/install/config.yaml | 381 ++++++++++++++++- .../basic-integration/install/description.md | 4 + 7 files changed, 1521 insertions(+), 17 deletions(-) diff --git a/context/skills/basic-integration/capture/config.yaml b/context/skills/basic-integration/capture/config.yaml index 98e99d55..618bc884 100644 --- a/context/skills/basic-integration/capture/config.yaml +++ b/context/skills/basic-integration/capture/config.yaml @@ -1,10 +1,383 @@ type: docs-only template: description.md description: Instrument the planned events with PostHog capture calls -tags: [orchestrator, capture] +tags: + - orchestrator + - capture +shared_docs: + - https://posthog.com/docs/product-analytics/best-practices.md variants: - - id: all - display_name: PostHog capture step - tags: [orchestrator, capture] + - 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/product-analytics/best-practices.md + - 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/error-tracking-step/config.yaml b/context/skills/basic-integration/error-tracking-step/config.yaml index 0d050f96..9cb1076e 100644 --- a/context/skills/basic-integration/error-tracking-step/config.yaml +++ b/context/skills/basic-integration/error-tracking-step/config.yaml @@ -1,8 +1,381 @@ type: docs-only template: description.md description: Capture exceptions with PostHog around critical flows -tags: [orchestrator, error-tracking] +tags: + - orchestrator + - error-tracking variants: - - id: all - display_name: PostHog error-tracking step - tags: [orchestrator, error-tracking] + - 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 index b2b5b91f..352bbea7 100644 --- a/context/skills/basic-integration/error-tracking-step/description.md +++ b/context/skills/basic-integration/error-tracking-step/description.md @@ -11,3 +11,7 @@ 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/init/config.yaml b/context/skills/basic-integration/init/config.yaml index 2100b785..f8683f88 100644 --- a/context/skills/basic-integration/init/config.yaml +++ b/context/skills/basic-integration/init/config.yaml @@ -1,8 +1,381 @@ type: docs-only template: description.md description: Initialize PostHog and set its environment variables -tags: [orchestrator, init] +tags: + - orchestrator + - init variants: - - id: all - display_name: PostHog init step - tags: [orchestrator, init] + - 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 index b550d169..2440423e 100644 --- a/context/skills/basic-integration/init/description.md +++ b/context/skills/basic-integration/init/description.md @@ -16,3 +16,7 @@ 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 index 0bb3fd1d..34c5a473 100644 --- a/context/skills/basic-integration/install/config.yaml +++ b/context/skills/basic-integration/install/config.yaml @@ -1,8 +1,381 @@ type: docs-only template: description.md description: Install the PostHog SDK with the project's package manager -tags: [orchestrator, install] +tags: + - orchestrator + - install variants: - - id: all - display_name: PostHog install step - tags: [orchestrator, install] + - 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 index cb6bdb9b..f914b263 100644 --- a/context/skills/basic-integration/install/description.md +++ b/context/skills/basic-integration/install/description.md @@ -12,3 +12,7 @@ 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} From 2f51b16bf0b4431f22cff4350f31bd480edc0815 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Thu, 9 Jul 2026 18:51:59 -0400 Subject: [PATCH 18/38] refactor(orchestrator): flow-scoped agents, posthog-integration step-skills (role internal), variants_from Co-Authored-By: Claude Fable 5 --- .../agents/{ => posthog-integration}/build.md | 2 +- .../{ => posthog-integration}/capture.md | 2 +- .../{ => posthog-integration}/dashboard.md | 2 +- .../error-tracking.md | 2 +- .../{ => posthog-integration}/identify.md | 2 +- .../agents/{ => posthog-integration}/init.md | 2 +- .../{ => posthog-integration}/install.md | 2 +- .../integrate-posthog.md | 0 .../{ => posthog-integration}/report.md | 2 +- .../basic-integration/capture/config.yaml | 383 ------------------ .../error-tracking-step/config.yaml | 381 ----------------- .../skills/basic-integration/init/config.yaml | 381 ----------------- .../basic-integration/install/config.yaml | 381 ----------------- .../build/config.yaml | 2 + .../build/description.md | 0 .../posthog-integration/capture/config.yaml | 9 + .../capture/description.md | 0 .../dashboard/config.yaml | 2 + .../dashboard/description.md | 0 .../error-tracking-step/config.yaml | 9 + .../error-tracking-step/description.md | 0 .../identify/config.yaml | 2 + .../identify/description.md | 0 .../posthog-integration/init/config.yaml | 9 + .../init/description.md | 0 .../posthog-integration/install/config.yaml | 9 + .../install/description.md | 0 .../report/config.yaml | 2 + .../report/description.md | 0 scripts/lib/agent-generator.js | 104 +++-- scripts/lib/skill-generator.js | 36 +- scripts/lib/tests/skill-variants-from.test.js | 116 ++++++ 32 files changed, 274 insertions(+), 1568 deletions(-) rename context/agents/{ => posthog-integration}/build.md (96%) rename context/agents/{ => posthog-integration}/capture.md (94%) rename context/agents/{ => posthog-integration}/dashboard.md (92%) rename context/agents/{ => posthog-integration}/error-tracking.md (95%) rename context/agents/{ => posthog-integration}/identify.md (92%) rename context/agents/{ => posthog-integration}/init.md (93%) rename context/agents/{ => posthog-integration}/install.md (93%) rename context/agents/{ => posthog-integration}/integrate-posthog.md (100%) rename context/agents/{ => posthog-integration}/report.md (94%) delete mode 100644 context/skills/basic-integration/capture/config.yaml delete mode 100644 context/skills/basic-integration/error-tracking-step/config.yaml delete mode 100644 context/skills/basic-integration/init/config.yaml delete mode 100644 context/skills/basic-integration/install/config.yaml rename context/skills/{basic-integration => posthog-integration}/build/config.yaml (91%) rename context/skills/{basic-integration => posthog-integration}/build/description.md (100%) create mode 100644 context/skills/posthog-integration/capture/config.yaml rename context/skills/{basic-integration => posthog-integration}/capture/description.md (100%) rename context/skills/{basic-integration => posthog-integration}/dashboard/config.yaml (92%) rename context/skills/{basic-integration => posthog-integration}/dashboard/description.md (100%) create mode 100644 context/skills/posthog-integration/error-tracking-step/config.yaml rename context/skills/{basic-integration => posthog-integration}/error-tracking-step/description.md (100%) rename context/skills/{basic-integration => posthog-integration}/identify/config.yaml (94%) rename context/skills/{basic-integration => posthog-integration}/identify/description.md (100%) create mode 100644 context/skills/posthog-integration/init/config.yaml rename context/skills/{basic-integration => posthog-integration}/init/description.md (100%) create mode 100644 context/skills/posthog-integration/install/config.yaml rename context/skills/{basic-integration => posthog-integration}/install/description.md (100%) rename context/skills/{basic-integration => posthog-integration}/report/config.yaml (91%) rename context/skills/{basic-integration => posthog-integration}/report/description.md (100%) create mode 100644 scripts/lib/tests/skill-variants-from.test.js diff --git a/context/agents/build.md b/context/agents/posthog-integration/build.md similarity index 96% rename from context/agents/build.md rename to context/agents/posthog-integration/build.md index 77243bab..7a4bb84f 100644 --- a/context/agents/build.md +++ b/context/agents/posthog-integration/build.md @@ -3,7 +3,7 @@ type: build flow: posthog-integration label: Install dependencies and build model: claude-sonnet-4-6 -skills: [basic-integration-build] +skills: [posthog-integration-build] allowedTools: [Read, Edit, Glob, Grep, Bash] disallowedTools: [enqueue_task] dependsOn: [install, init, identify, error-tracking, capture] diff --git a/context/agents/capture.md b/context/agents/posthog-integration/capture.md similarity index 94% rename from context/agents/capture.md rename to context/agents/posthog-integration/capture.md index db5a77c4..e8c307d5 100644 --- a/context/agents/capture.md +++ b/context/agents/posthog-integration/capture.md @@ -3,7 +3,7 @@ type: capture flow: posthog-integration label: Capture events model: claude-sonnet-4-6 -skills: [basic-integration-capture] +skills: [posthog-integration-capture] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [install, init] diff --git a/context/agents/dashboard.md b/context/agents/posthog-integration/dashboard.md similarity index 92% rename from context/agents/dashboard.md rename to context/agents/posthog-integration/dashboard.md index 54c336de..bfad4b77 100644 --- a/context/agents/dashboard.md +++ b/context/agents/posthog-integration/dashboard.md @@ -3,7 +3,7 @@ type: dashboard flow: posthog-integration label: Create a starter dashboard model: claude-sonnet-4-6 -skills: [basic-integration-dashboard] +skills: [posthog-integration-dashboard] allowedTools: [Read, Glob, Grep] disallowedTools: [Write, Edit, Bash, enqueue_task] dependsOn: [build] diff --git a/context/agents/error-tracking.md b/context/agents/posthog-integration/error-tracking.md similarity index 95% rename from context/agents/error-tracking.md rename to context/agents/posthog-integration/error-tracking.md index c7e2aea3..a486dcc7 100644 --- a/context/agents/error-tracking.md +++ b/context/agents/posthog-integration/error-tracking.md @@ -3,7 +3,7 @@ type: error-tracking flow: posthog-integration label: Add error tracking model: claude-sonnet-4-6 -skills: [basic-integration-error-tracking-step] +skills: [posthog-integration-error-tracking-step] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [install, init] diff --git a/context/agents/identify.md b/context/agents/posthog-integration/identify.md similarity index 92% rename from context/agents/identify.md rename to context/agents/posthog-integration/identify.md index 658afca9..ccbd5779 100644 --- a/context/agents/identify.md +++ b/context/agents/posthog-integration/identify.md @@ -3,7 +3,7 @@ type: identify flow: posthog-integration label: Wire user identification model: claude-sonnet-4-6 -skills: [basic-integration-identify] +skills: [posthog-integration-identify] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [install, init] diff --git a/context/agents/init.md b/context/agents/posthog-integration/init.md similarity index 93% rename from context/agents/init.md rename to context/agents/posthog-integration/init.md index ffc62c2d..fd86e2b5 100644 --- a/context/agents/init.md +++ b/context/agents/posthog-integration/init.md @@ -3,7 +3,7 @@ type: init flow: posthog-integration label: Set up PostHog initialization model: claude-haiku-4-5-20251001 -skills: [basic-integration-init] +skills: [posthog-integration-init] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [] diff --git a/context/agents/install.md b/context/agents/posthog-integration/install.md similarity index 93% rename from context/agents/install.md rename to context/agents/posthog-integration/install.md index 4ed83e18..455c2e20 100644 --- a/context/agents/install.md +++ b/context/agents/posthog-integration/install.md @@ -3,7 +3,7 @@ type: install flow: posthog-integration label: Add the PostHog SDK to the manifest model: claude-haiku-4-5-20251001 -skills: [basic-integration-install] +skills: [posthog-integration-install] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [] diff --git a/context/agents/integrate-posthog.md b/context/agents/posthog-integration/integrate-posthog.md similarity index 100% rename from context/agents/integrate-posthog.md rename to context/agents/posthog-integration/integrate-posthog.md diff --git a/context/agents/report.md b/context/agents/posthog-integration/report.md similarity index 94% rename from context/agents/report.md rename to context/agents/posthog-integration/report.md index d9db8a69..9bd45a90 100644 --- a/context/agents/report.md +++ b/context/agents/posthog-integration/report.md @@ -3,7 +3,7 @@ type: report flow: posthog-integration label: Write the setup report model: claude-sonnet-4-6 -skills: [basic-integration-report] +skills: [posthog-integration-report] allowedTools: [Read, Write, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [dashboard] diff --git a/context/skills/basic-integration/capture/config.yaml b/context/skills/basic-integration/capture/config.yaml deleted file mode 100644 index 618bc884..00000000 --- a/context/skills/basic-integration/capture/config.yaml +++ /dev/null @@ -1,383 +0,0 @@ -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/error-tracking-step/config.yaml b/context/skills/basic-integration/error-tracking-step/config.yaml deleted file mode 100644 index 9cb1076e..00000000 --- a/context/skills/basic-integration/error-tracking-step/config.yaml +++ /dev/null @@ -1,381 +0,0 @@ -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/init/config.yaml b/context/skills/basic-integration/init/config.yaml deleted file mode 100644 index f8683f88..00000000 --- a/context/skills/basic-integration/init/config.yaml +++ /dev/null @@ -1,381 +0,0 @@ -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/install/config.yaml b/context/skills/basic-integration/install/config.yaml deleted file mode 100644 index 34c5a473..00000000 --- a/context/skills/basic-integration/install/config.yaml +++ /dev/null @@ -1,381 +0,0 @@ -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/build/config.yaml b/context/skills/posthog-integration/build/config.yaml similarity index 91% rename from context/skills/basic-integration/build/config.yaml rename to context/skills/posthog-integration/build/config.yaml index 82142d68..61265467 100644 --- a/context/skills/basic-integration/build/config.yaml +++ b/context/skills/posthog-integration/build/config.yaml @@ -7,3 +7,5 @@ variants: display_name: PostHog build step tags: [orchestrator, build] docs_urls: [] +cli: + role: internal diff --git a/context/skills/basic-integration/build/description.md b/context/skills/posthog-integration/build/description.md similarity index 100% rename from context/skills/basic-integration/build/description.md rename to context/skills/posthog-integration/build/description.md diff --git a/context/skills/posthog-integration/capture/config.yaml b/context/skills/posthog-integration/capture/config.yaml new file mode 100644 index 00000000..22ad9dd6 --- /dev/null +++ b/context/skills/posthog-integration/capture/config.yaml @@ -0,0 +1,9 @@ +# Orchestrator step-skill: fetched by task agents, never surfaced as a command. +# The framework matrix is borrowed from the canonical integration group. +type: docs-only +template: description.md +description: Instrument the planned events with PostHog capture calls +tags: [orchestrator, capture] +cli: + role: internal +variants_from: integration diff --git a/context/skills/basic-integration/capture/description.md b/context/skills/posthog-integration/capture/description.md similarity index 100% rename from context/skills/basic-integration/capture/description.md rename to context/skills/posthog-integration/capture/description.md diff --git a/context/skills/basic-integration/dashboard/config.yaml b/context/skills/posthog-integration/dashboard/config.yaml similarity index 92% rename from context/skills/basic-integration/dashboard/config.yaml rename to context/skills/posthog-integration/dashboard/config.yaml index affa5328..f5cc272e 100644 --- a/context/skills/basic-integration/dashboard/config.yaml +++ b/context/skills/posthog-integration/dashboard/config.yaml @@ -7,3 +7,5 @@ variants: display_name: PostHog dashboard step tags: [orchestrator, dashboard] docs_urls: [] +cli: + role: internal diff --git a/context/skills/basic-integration/dashboard/description.md b/context/skills/posthog-integration/dashboard/description.md similarity index 100% rename from context/skills/basic-integration/dashboard/description.md rename to context/skills/posthog-integration/dashboard/description.md diff --git a/context/skills/posthog-integration/error-tracking-step/config.yaml b/context/skills/posthog-integration/error-tracking-step/config.yaml new file mode 100644 index 00000000..9e7dc25a --- /dev/null +++ b/context/skills/posthog-integration/error-tracking-step/config.yaml @@ -0,0 +1,9 @@ +# Orchestrator step-skill: fetched by task agents, never surfaced as a command. +# The framework matrix is borrowed from the canonical integration group. +type: docs-only +template: description.md +description: Capture exceptions with PostHog around critical flows +tags: [orchestrator, error-tracking] +cli: + role: internal +variants_from: integration diff --git a/context/skills/basic-integration/error-tracking-step/description.md b/context/skills/posthog-integration/error-tracking-step/description.md similarity index 100% rename from context/skills/basic-integration/error-tracking-step/description.md rename to context/skills/posthog-integration/error-tracking-step/description.md diff --git a/context/skills/basic-integration/identify/config.yaml b/context/skills/posthog-integration/identify/config.yaml similarity index 94% rename from context/skills/basic-integration/identify/config.yaml rename to context/skills/posthog-integration/identify/config.yaml index f257eeb4..6def463a 100644 --- a/context/skills/basic-integration/identify/config.yaml +++ b/context/skills/posthog-integration/identify/config.yaml @@ -9,3 +9,5 @@ variants: docs_urls: - https://posthog.com/docs/getting-started/identify-users.md - https://posthog.com/docs/product-analytics/identity-resolution.md +cli: + role: internal diff --git a/context/skills/basic-integration/identify/description.md b/context/skills/posthog-integration/identify/description.md similarity index 100% rename from context/skills/basic-integration/identify/description.md rename to context/skills/posthog-integration/identify/description.md diff --git a/context/skills/posthog-integration/init/config.yaml b/context/skills/posthog-integration/init/config.yaml new file mode 100644 index 00000000..9392ae80 --- /dev/null +++ b/context/skills/posthog-integration/init/config.yaml @@ -0,0 +1,9 @@ +# Orchestrator step-skill: fetched by task agents, never surfaced as a command. +# The framework matrix is borrowed from the canonical integration group. +type: docs-only +template: description.md +description: Initialize PostHog and set its environment variables +tags: [orchestrator, init] +cli: + role: internal +variants_from: integration diff --git a/context/skills/basic-integration/init/description.md b/context/skills/posthog-integration/init/description.md similarity index 100% rename from context/skills/basic-integration/init/description.md rename to context/skills/posthog-integration/init/description.md diff --git a/context/skills/posthog-integration/install/config.yaml b/context/skills/posthog-integration/install/config.yaml new file mode 100644 index 00000000..a27929d2 --- /dev/null +++ b/context/skills/posthog-integration/install/config.yaml @@ -0,0 +1,9 @@ +# Orchestrator step-skill: fetched by task agents, never surfaced as a command. +# The framework matrix is borrowed from the canonical integration group. +type: docs-only +template: description.md +description: Install the PostHog SDK with the project's package manager +tags: [orchestrator, install] +cli: + role: internal +variants_from: integration diff --git a/context/skills/basic-integration/install/description.md b/context/skills/posthog-integration/install/description.md similarity index 100% rename from context/skills/basic-integration/install/description.md rename to context/skills/posthog-integration/install/description.md diff --git a/context/skills/basic-integration/report/config.yaml b/context/skills/posthog-integration/report/config.yaml similarity index 91% rename from context/skills/basic-integration/report/config.yaml rename to context/skills/posthog-integration/report/config.yaml index 1c454835..4215277d 100644 --- a/context/skills/basic-integration/report/config.yaml +++ b/context/skills/posthog-integration/report/config.yaml @@ -7,3 +7,5 @@ variants: display_name: PostHog report step tags: [orchestrator, report] docs_urls: [] +cli: + role: internal diff --git a/context/skills/basic-integration/report/description.md b/context/skills/posthog-integration/report/description.md similarity index 100% rename from context/skills/basic-integration/report/description.md rename to context/skills/posthog-integration/report/description.md diff --git a/scripts/lib/agent-generator.js b/scripts/lib/agent-generator.js index d787152d..10689301 100644 --- a/scripts/lib/agent-generator.js +++ b/scripts/lib/agent-generator.js @@ -1,15 +1,15 @@ /** * 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. + * An agent prompt is one markdown file per task type, grouped in a folder per + * flow. 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 + * Source: context/agents//.md + * Output: dist/agents//.md + dist/agents/agent-menu.json */ import fs from 'fs'; @@ -18,22 +18,53 @@ 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) { +/** + * The agent prompts available in source: one { flow, id } per + * `/.md`. README.md files are author documentation, not served + * prompts. A markdown file directly under agents/ is a layout error — prompts + * are always flow-scoped. + */ +export function loadAgentEntries(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(); + const entries = []; + for (const dirent of fs.readdirSync(agentsSourceDir, { withFileTypes: true })) { + if (dirent.name === 'README.md') continue; + if (dirent.isFile() && dirent.name.endsWith('.md')) { + throw new Error( + `Agent prompt "${dirent.name}" sits directly under agents/ — move it into a flow folder (agents//${dirent.name})`, + ); + } + if (!dirent.isDirectory()) continue; + const flow = dirent.name; + const flowDir = path.join(agentsSourceDir, flow); + for (const file of fs.readdirSync(flowDir)) { + if (!file.endsWith('.md') || file === 'README.md') continue; + entries.push({ flow, id: file.slice(0, -'.md'.length) }); + } + } + return entries.sort((a, b) => a.flow.localeCompare(b.flow) || a.id.localeCompare(b.id)); } /** - * 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 }. + * A prompt's frontmatter `flow:` must match its folder — the folder is the + * registry scope, the frontmatter keeps the file self-describing on disk. + */ +function assertFlowMatches(sourcePath, flow) { + const text = fs.readFileSync(sourcePath, 'utf8'); + const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---/); + const declared = match?.[1].match(/^flow:\s*(.+?)\s*$/m)?.[1]; + if (declared && declared !== flow) { + throw new Error( + `Agent prompt ${sourcePath} declares flow "${declared}" but lives in agents/${flow}/`, + ); + } +} + +/** + * Copy every agent-prompt markdown file into dist/agents// and write the + * menu the wizard fetches to discover available types. Each menu entry carries + * its flow and a full downloadUrl 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'); @@ -42,14 +73,14 @@ export function buildAgents({ configDir, distDir, baseUrl, version = 'dev' }) { fs.mkdirSync(agentsDistDir, { recursive: true }); - const ids = loadAgentIds(agentsSourceDir); + const entries = loadAgentEntries(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` }); + for (const { flow, id } of entries) { + const sourcePath = path.join(agentsSourceDir, flow, `${id}.md`); + assertFlowMatches(sourcePath, flow); + fs.mkdirSync(path.join(agentsDistDir, flow), { recursive: true }); + fs.copyFileSync(sourcePath, path.join(agentsDistDir, flow, `${id}.md`)); + agents.push({ id, flow, downloadUrl: `${resolvedBase}/${flow}/${id}.md` }); } const menu = { version: '1.0', buildVersion: version, agents }; @@ -58,12 +89,21 @@ export function buildAgents({ configDir, distDir, baseUrl, version = 'dev' }) { JSON.stringify(menu, null, 2) + '\n', ); - // Reconcile: drop dist files whose source markdown was removed. - const keep = new Set(ids.map(id => `${id}.md`)); + // Reconcile: drop dist files and folders whose source markdown was removed. + const keep = new Set(entries.map(e => path.join(e.flow, `${e.id}.md`))); keep.add('agent-menu.json'); - for (const file of fs.readdirSync(agentsDistDir)) { - if (!keep.has(file)) fs.rmSync(path.join(agentsDistDir, file)); - } + const walk = dir => { + for (const dirent of fs.readdirSync(dir, { withFileTypes: true })) { + const abs = path.join(dir, dirent.name); + if (dirent.isDirectory()) { + walk(abs); + if (fs.readdirSync(abs).length === 0) fs.rmdirSync(abs); + } else if (!keep.has(path.relative(agentsDistDir, abs))) { + fs.rmSync(abs); + } + } + }; + walk(agentsDistDir); return { count: agents.length, agentsDistDir }; } diff --git a/scripts/lib/skill-generator.js b/scripts/lib/skill-generator.js index e579d650..7311cf7c 100644 --- a/scripts/lib/skill-generator.js +++ b/scripts/lib/skill-generator.js @@ -160,7 +160,7 @@ function loadSkillsConfig(configDir) { const configFile = path.join(dir, 'config.yaml'); if (fs.existsSync(configFile)) { const localConfig = loadYaml(configFile); - if (localConfig?.variants) { + if (localConfig?.variants || localConfig?.variants_from) { config[keyParts.join('/')] = localConfig; } } @@ -209,13 +209,45 @@ function normalizeExamplePaths(value) { return Array.isArray(value) ? value : [value]; } +/** + * Resolve `variants_from` references: a group may borrow another group's + * variant matrix instead of duplicating it. Only the framework identity comes + * across — id, display_name, tags, docs_urls — never example paths, templates, + * cli blocks, or shared docs, which stay the borrowing group's own concern. + * One level only; a source group must declare its variants literally. + */ +function resolveVariantsFrom(config) { + for (const [key, group] of Object.entries(config)) { + if (!group.variants_from) continue; + if (group.variants) { + if (group._variantsResolved) continue; + throw new Error(`Skill group "${key}": declare either variants or variants_from, not both`); + } + const source = config[group.variants_from]; + if (!source) { + throw new Error(`Skill group "${key}": variants_from "${group.variants_from}" does not name a skill group`); + } + if (source.variants_from) { + throw new Error(`Skill group "${key}": variants_from cannot chain ("${group.variants_from}" also uses variants_from)`); + } + group.variants = source.variants.map(v => { + const variant = { id: v.id, display_name: v.display_name }; + if (v.tags) variant.tags = [...v.tags]; + if (v.docs_urls) variant.docs_urls = [...v.docs_urls]; + return variant; + }); + group._variantsResolved = true; + } +} + /** * Expand grouped skill config into a flat array of skill objects. * Each top-level key (except shared_docs) is a skill group with - * base properties and a variants array. + * base properties and a variants array (literal or via variants_from). */ function expandSkillGroups(config, configDir) { const skills = []; + resolveVariantsFrom(config); for (const [key, group] of Object.entries(config)) { if (key === 'shared_docs') continue; diff --git a/scripts/lib/tests/skill-variants-from.test.js b/scripts/lib/tests/skill-variants-from.test.js new file mode 100644 index 00000000..f3bcbd79 --- /dev/null +++ b/scripts/lib/tests/skill-variants-from.test.js @@ -0,0 +1,116 @@ +import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { mkdirSync, writeFileSync, mkdtempSync, rmSync } from 'fs'; +import { join } from 'path'; +import { tmpdir } from 'os'; + +import { expandSkillGroups } from '../skill-generator.js'; + +function createFixture(tree, baseDir) { + for (const [name, content] of Object.entries(tree)) { + const fullPath = join(baseDir, name); + if (typeof content === 'string') { + writeFileSync(fullPath, content); + } else { + mkdirSync(fullPath, { recursive: true }); + createFixture(content, fullPath); + } + } +} + +describe('variants_from', () => { + let tmpDir; + + beforeEach(() => { + tmpDir = mkdtempSync(join(tmpdir(), 'skills-test-')); + mkdirSync(join(tmpDir, 'skills')); + createFixture({ + skills: { + integration: { 'description.md': '# Integration for {display_name}' }, + 'flow-x': { install: { 'description.md': '# Install for {display_name}' } }, + }, + }, tmpDir); + }); + + afterEach(() => rmSync(tmpDir, { recursive: true, force: true })); + + const integrationGroup = () => ({ + type: 'skill', + template: 'description.md', + variants: [ + { + id: 'django', + display_name: 'Django', + tags: ['django', 'python'], + docs_urls: ['https://posthog.com/docs/libraries/django.md'], + example_paths: 'example-apps/django', + }, + ], + }); + + const borrowingGroup = () => ({ + type: 'docs-only', + template: 'description.md', + tags: ['orchestrator', 'install'], + variants_from: 'integration', + }); + + it('borrows the source matrix: id, display_name, tags, docs_urls', () => { + const config = { integration: integrationGroup(), 'flow-x/install': borrowingGroup() }; + const skills = expandSkillGroups(config, tmpDir); + const step = skills.find(s => s.id === 'flow-x-install-django'); + expect(step).toBeDefined(); + expect(step.display_name).toBe('Django'); + expect(step.docs_urls).toEqual(['https://posthog.com/docs/libraries/django.md']); + }); + + it('merges the borrowing group tags with the source variant tags', () => { + const config = { integration: integrationGroup(), 'flow-x/install': borrowingGroup() }; + const skills = expandSkillGroups(config, tmpDir); + const step = skills.find(s => s.id === 'flow-x-install-django'); + expect(step.tags).toEqual(['orchestrator', 'install', 'django', 'python']); + }); + + it('does not inherit example paths from the source variants', () => { + const config = { integration: integrationGroup(), 'flow-x/install': borrowingGroup() }; + const skills = expandSkillGroups(config, tmpDir); + const step = skills.find(s => s.id === 'flow-x-install-django'); + expect(step._examplePaths).toEqual([]); + }); + + it('leaves the source group untouched', () => { + const config = { integration: integrationGroup(), 'flow-x/install': borrowingGroup() }; + const skills = expandSkillGroups(config, tmpDir); + const source = skills.find(s => s.id === 'integration-django'); + expect(source.tags).toEqual(['django', 'python']); + expect(source._examplePaths).toEqual(['example-apps/django']); + }); + + it('expanding the same config twice is stable', () => { + const config = { integration: integrationGroup(), 'flow-x/install': borrowingGroup() }; + expandSkillGroups(config, tmpDir); + const skills = expandSkillGroups(config, tmpDir); + expect(skills.filter(s => s.id === 'flow-x-install-django')).toHaveLength(1); + }); + + it('throws when the source group does not exist', () => { + const config = { 'flow-x/install': { ...borrowingGroup(), variants_from: 'nope' } }; + expect(() => expandSkillGroups(config, tmpDir)).toThrow(/does not name a skill group/); + }); + + it('throws when a group declares both variants and variants_from', () => { + const config = { + integration: integrationGroup(), + 'flow-x/install': { ...borrowingGroup(), variants: [{ id: 'x', display_name: 'X' }] }, + }; + expect(() => expandSkillGroups(config, tmpDir)).toThrow(/not both/); + }); + + it('throws when variants_from chains', () => { + const config = { + integration: integrationGroup(), + 'flow-x/install': borrowingGroup(), + 'flow-x/init': { ...borrowingGroup(), variants_from: 'flow-x/install' }, + }; + expect(() => expandSkillGroups(config, tmpDir)).toThrow(/cannot chain/); + }); +}); From 9d0cccd680f954567ea70cbd99dd0bbe10f14a9a Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Thu, 9 Jul 2026 18:52:29 -0400 Subject: [PATCH 19/38] docs(agents): flow folders, gateway model ids, flat frontmatter rule Co-Authored-By: Claude Fable 5 --- context/agents/README.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/context/agents/README.md b/context/agents/README.md index 0737511d..df45256f 100644 --- a/context/agents/README.md +++ b/context/agents/README.md @@ -1,19 +1,26 @@ # 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. +One `/.md` per orchestrator task — the WHAT of the task. The folder +is the flow: the wizard's registry is scoped per flow, so audit or migration +agent sets get sibling folders. 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` +repeats the folder name so the file stays self-describing on disk (the build +rejects a mismatch), and one prompt per flow is marked `seed: true`: the +planner that seeds the queue, not an enqueueable task type. + +`model` is a gateway model id, not a runner binding — the wizard's switchboard +routes it, and its CLI/flag rungs may override it per run. `allowedTools` / +`disallowedTools` use the wizard's tool vocabulary; the executing harness maps +them to its native tool names. 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. +so a prompt never restates them. Frontmatter stays flat: scalars and inline +`[a, b]` arrays only, the wizard's parser is deliberately not a YAML engine. -This README is documentation, not data: the build serves every other `.md` in -this folder as an agent prompt. +This README is documentation, not data: the build serves every other `.md` +under a flow folder as an agent prompt. ```markdown --- From fb1fed0498e9c791593f9d79bff076d73b93530c Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Thu, 9 Jul 2026 19:08:30 -0400 Subject: [PATCH 20/38] fix(dev-server): serve flow-scoped agent prompts at /agents/{flow}/{type}.md Co-Authored-By: Claude Fable 5 --- scripts/dev-server.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/dev-server.js b/scripts/dev-server.js index 3d000740..d69cfa83 100644 --- a/scripts/dev-server.js +++ b/scripts/dev-server.js @@ -294,9 +294,9 @@ function createServer() { return; } - const agentMatch = req.url?.match(/^\/agents\/([\w-]+\.md)$/); + const agentMatch = req.url?.match(/^\/agents\/([\w-]+)\/([\w-]+\.md)$/); if (agentMatch) { - serveFile(res, path.join(agentsDir, agentMatch[1]), 'text/markdown; charset=utf-8'); + serveFile(res, path.join(agentsDir, agentMatch[1], agentMatch[2]), 'text/markdown; charset=utf-8'); return; } @@ -316,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\n /agent-menu.json\n /agents/{type}.md'); + 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/{flow}/{type}.md'); }); server.listen(PORT, () => { @@ -324,7 +324,7 @@ 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(`🤖 Agent prompt: http://localhost:${PORT}/agents/{flow}/{type}.md`); console.log(`📋 Agents menu: http://localhost:${PORT}/agent-menu.json`); }); From f9e686d3073f5afdf941a252054e4f10e0a9c286 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 14 Jul 2026 14:04:50 -0400 Subject: [PATCH 21/38] feat(agents): run orchestrator integration agents on gpt-5.6 luna for the mechanical short-context tasks (install, init), terra for the seed and the judgment tasks that read across the codebase. Co-Authored-By: Claude Opus 4.8 --- context/agents/posthog-integration/build.md | 2 +- context/agents/posthog-integration/capture.md | 2 +- context/agents/posthog-integration/dashboard.md | 2 +- context/agents/posthog-integration/error-tracking.md | 2 +- context/agents/posthog-integration/identify.md | 2 +- context/agents/posthog-integration/init.md | 2 +- context/agents/posthog-integration/install.md | 2 +- context/agents/posthog-integration/integrate-posthog.md | 2 +- context/agents/posthog-integration/report.md | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/context/agents/posthog-integration/build.md b/context/agents/posthog-integration/build.md index 7a4bb84f..b579d5f3 100644 --- a/context/agents/posthog-integration/build.md +++ b/context/agents/posthog-integration/build.md @@ -2,7 +2,7 @@ type: build flow: posthog-integration label: Install dependencies and build -model: claude-sonnet-4-6 +model: openai/gpt-5.6-terra skills: [posthog-integration-build] allowedTools: [Read, Edit, Glob, Grep, Bash] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/capture.md b/context/agents/posthog-integration/capture.md index e8c307d5..cfc56156 100644 --- a/context/agents/posthog-integration/capture.md +++ b/context/agents/posthog-integration/capture.md @@ -2,7 +2,7 @@ type: capture flow: posthog-integration label: Capture events -model: claude-sonnet-4-6 +model: openai/gpt-5.6-terra skills: [posthog-integration-capture] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/dashboard.md b/context/agents/posthog-integration/dashboard.md index bfad4b77..b0a99c97 100644 --- a/context/agents/posthog-integration/dashboard.md +++ b/context/agents/posthog-integration/dashboard.md @@ -2,7 +2,7 @@ type: dashboard flow: posthog-integration label: Create a starter dashboard -model: claude-sonnet-4-6 +model: openai/gpt-5.6-terra skills: [posthog-integration-dashboard] allowedTools: [Read, Glob, Grep] disallowedTools: [Write, Edit, Bash, enqueue_task] diff --git a/context/agents/posthog-integration/error-tracking.md b/context/agents/posthog-integration/error-tracking.md index a486dcc7..8e4900ce 100644 --- a/context/agents/posthog-integration/error-tracking.md +++ b/context/agents/posthog-integration/error-tracking.md @@ -2,7 +2,7 @@ type: error-tracking flow: posthog-integration label: Add error tracking -model: claude-sonnet-4-6 +model: openai/gpt-5.6-terra skills: [posthog-integration-error-tracking-step] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/identify.md b/context/agents/posthog-integration/identify.md index ccbd5779..c7297e5d 100644 --- a/context/agents/posthog-integration/identify.md +++ b/context/agents/posthog-integration/identify.md @@ -2,7 +2,7 @@ type: identify flow: posthog-integration label: Wire user identification -model: claude-sonnet-4-6 +model: openai/gpt-5.6-terra skills: [posthog-integration-identify] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/init.md b/context/agents/posthog-integration/init.md index fd86e2b5..baa8d9ba 100644 --- a/context/agents/posthog-integration/init.md +++ b/context/agents/posthog-integration/init.md @@ -2,7 +2,7 @@ type: init flow: posthog-integration label: Set up PostHog initialization -model: claude-haiku-4-5-20251001 +model: openai/gpt-5.6-luna skills: [posthog-integration-init] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/install.md b/context/agents/posthog-integration/install.md index 455c2e20..283cee8c 100644 --- a/context/agents/posthog-integration/install.md +++ b/context/agents/posthog-integration/install.md @@ -2,7 +2,7 @@ type: install flow: posthog-integration label: Add the PostHog SDK to the manifest -model: claude-haiku-4-5-20251001 +model: openai/gpt-5.6-luna skills: [posthog-integration-install] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/integrate-posthog.md b/context/agents/posthog-integration/integrate-posthog.md index 904ef74f..f6662144 100644 --- a/context/agents/posthog-integration/integrate-posthog.md +++ b/context/agents/posthog-integration/integrate-posthog.md @@ -2,7 +2,7 @@ type: integrate-posthog flow: posthog-integration seed: true -model: claude-sonnet-4-6 +model: openai/gpt-5.6-terra skills: [] allowedTools: [Read, Glob, Grep] disallowedTools: [Write, Edit, Bash, complete_task] diff --git a/context/agents/posthog-integration/report.md b/context/agents/posthog-integration/report.md index 9bd45a90..41392663 100644 --- a/context/agents/posthog-integration/report.md +++ b/context/agents/posthog-integration/report.md @@ -2,7 +2,7 @@ type: report flow: posthog-integration label: Write the setup report -model: claude-sonnet-4-6 +model: openai/gpt-5.6-terra skills: [posthog-integration-report] allowedTools: [Read, Write, Glob, Grep] disallowedTools: [enqueue_task] From 1ee85521c21efd00776f25d7e657b46900a04b7b Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 14 Jul 2026 16:43:15 -0400 Subject: [PATCH 22/38] fix(agents): address orchestrator benchmark remarks Give capture Write so it can create the events cache, drop the fenced test suite from build verification, and make the report reconstruct a missing event manifest and skip the pre-create read. Co-Authored-By: Claude Opus 4.8 --- context/agents/posthog-integration/build.md | 4 ++-- context/agents/posthog-integration/capture.md | 2 +- context/skills/posthog-integration/build/description.md | 8 +++++--- context/skills/posthog-integration/report/description.md | 4 ++++ 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/context/agents/posthog-integration/build.md b/context/agents/posthog-integration/build.md index b579d5f3..8abc05b0 100644 --- a/context/agents/posthog-integration/build.md +++ b/context/agents/posthog-integration/build.md @@ -12,13 +12,13 @@ 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 +declared, then verify the project builds and lints. 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 +The install completes and the build and lint 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 diff --git a/context/agents/posthog-integration/capture.md b/context/agents/posthog-integration/capture.md index cfc56156..236d1d38 100644 --- a/context/agents/posthog-integration/capture.md +++ b/context/agents/posthog-integration/capture.md @@ -4,7 +4,7 @@ flow: posthog-integration label: Capture events model: openai/gpt-5.6-terra skills: [posthog-integration-capture] -allowedTools: [Read, Edit, Glob, Grep] +allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [install, init] --- diff --git a/context/skills/posthog-integration/build/description.md b/context/skills/posthog-integration/build/description.md index aa9356cf..db9732b8 100644 --- a/context/skills/posthog-integration/build/description.md +++ b/context/skills/posthog-integration/build/description.md @@ -13,9 +13,11 @@ 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. +Run the project's build (or typecheck) and lint scripts if they exist +(check the manifest's scripts). Do not run the test suite — the runtime only +permits install, build, typecheck, lint, and format commands, so a test command +is blocked; a build that compiles is sufficient verification. 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. diff --git a/context/skills/posthog-integration/report/description.md b/context/skills/posthog-integration/report/description.md index 186303d7..4312fccd 100644 --- a/context/skills/posthog-integration/report/description.md +++ b/context/skills/posthog-integration/report/description.md @@ -1,12 +1,16 @@ # Write the setup report Write `posthog-setup-report.md` at the project root summarizing the integration. +It is a new file you create — write it directly, do not read it first. 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. + If that file is missing or empty, reconstruct the list instead of dropping the + table: grep the changed files for `capture(` calls and read the capture step's + handoff in `queue.json`. Include: From 08661e5955986ba8bde8439d64cfbc42043b7d07 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 14 Jul 2026 17:01:32 -0400 Subject: [PATCH 23/38] feat(agents): document PostHog env keys in .env.example during init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The init step now writes the required key names (placeholder values) to .env.example so other developers know what to set — the env-documentation gap the rubric flags. Co-Authored-By: Claude Opus 4.8 --- context/agents/posthog-integration/init.md | 7 ++++--- context/skills/posthog-integration/init/description.md | 6 ++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/context/agents/posthog-integration/init.md b/context/agents/posthog-integration/init.md index baa8d9ba..c3aa1727 100644 --- a/context/agents/posthog-integration/init.md +++ b/context/agents/posthog-integration/init.md @@ -12,10 +12,11 @@ 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. +once and available across the app, set the PostHog environment variables through +the wizard tools, and document those keys in `.env.example` for other developers. ## 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. +file, never hardcoded in source, and `.env.example` lists the key names (with +placeholder values) so the next developer knows what to set. diff --git a/context/skills/posthog-integration/init/description.md b/context/skills/posthog-integration/init/description.md index 2440423e..bf283ce5 100644 --- a/context/skills/posthog-integration/init/description.md +++ b/context/skills/posthog-integration/init/description.md @@ -10,6 +10,12 @@ Use the framework's public env-var convention so the client can read them. - the public project token - the PostHog host +Then document these keys for other developers: add them to `.env.example` (create +it if the project has none), with the real names and empty or placeholder values — +never the real secret. This file is committed, so the next developer knows which +keys to set. The example file is the only `.env*` you may write directly; the +actual `.env` still goes through `set_env_values`. + ## Init point Create the framework's single initialization point that runs once on the client, From 4dafc79bd51c20da4155dd64e67805fd2e23ede6 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 14 Jul 2026 17:03:29 -0400 Subject: [PATCH 24/38] fix(agents): build completes-with-conflict on pre-existing breakage, not failed A failed build blocks the dashboard and report that depend on it, so a build that fails only on pre-existing errors the integration never touched now completes as done with a conflict note; failed is reserved for integration-caused breakage. Co-Authored-By: Claude Opus 4.8 --- context/agents/posthog-integration/build.md | 9 +++++---- context/skills/posthog-integration/build/description.md | 8 ++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/context/agents/posthog-integration/build.md b/context/agents/posthog-integration/build.md index 8abc05b0..d2322b66 100644 --- a/context/agents/posthog-integration/build.md +++ b/context/agents/posthog-integration/build.md @@ -18,8 +18,9 @@ and is checked. ## How you know you succeeded -The install completes and the build and lint 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 +The install completes and the integration is in place. If the build or lint fails +only on pre-existing errors you did not introduce, that still counts as done — +note the conflict and finish. Reserve a failed status for when your own changes +break the build. Put a one-line summary of any conflict 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/skills/posthog-integration/build/description.md b/context/skills/posthog-integration/build/description.md index db9732b8..3cd4be1d 100644 --- a/context/skills/posthog-integration/build/description.md +++ b/context/skills/posthog-integration/build/description.md @@ -35,3 +35,11 @@ build break, an install that won't resolve, an environment issue unrelated to th 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. + +Complete this task with status **done** whenever the integration itself is in +place — even if the build or typecheck still fails on pre-existing errors in files +you never touched. Note the pre-existing failure in `conflict` and move on. Only +use status **failed** when your own integration changes are what break the build +and you cannot resolve them. A `failed` status stops later steps that depend on +this one (the dashboard and report), so do not fail the task over breakage the +integration did not cause. From de88ab5030a46eb0cb74b0d391dcd19c5657b58b Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 14 Jul 2026 17:11:53 -0400 Subject: [PATCH 25/38] feat(agents): make the build step review the integration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The build/review step now reviews every change before the report: it builds (and reports a failure clearly in the handoff), checks the added code matches the project's conventions, and confirms no unrelated file was edited or mangled — the things users complain about most. Co-Authored-By: Claude Opus 4.8 --- context/agents/posthog-integration/build.md | 19 ++++++------- .../posthog-integration/build/description.md | 27 ++++++++++++++++--- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/context/agents/posthog-integration/build.md b/context/agents/posthog-integration/build.md index d2322b66..f836e13f 100644 --- a/context/agents/posthog-integration/build.md +++ b/context/agents/posthog-integration/build.md @@ -1,7 +1,7 @@ --- type: build flow: posthog-integration -label: Install dependencies and build +label: Build and review the integration model: openai/gpt-5.6-terra skills: [posthog-integration-build] allowedTools: [Read, Edit, Glob, Grep, Bash] @@ -11,16 +11,17 @@ dependsOn: [install, init, identify, error-tracking, capture] ## Goal -Bring the integration together: install the dependencies the earlier steps -declared, then verify the project builds and lints. Until now -the steps only edited code and the manifest — this is where it actually installs -and is checked. +Bring the integration together and review it: install the dependencies the earlier +steps declared, verify the project builds and lints, then review every change for +convention fit and unintended edits. Until now the steps only edited code and the +manifest — this is where it installs, is checked, and is reviewed as a whole. ## How you know you succeeded -The install completes and the integration is in place. If the build or lint fails -only on pre-existing errors you did not introduce, that still counts as done — -note the conflict and finish. Reserve a failed status for when your own changes -break the build. Put a one-line summary of any conflict in your handoff's +The install completes, the integration is in place, and the changes read like the +rest of the codebase with nothing unrelated touched or mangled. If the build or +lint fails only on pre-existing errors you did not introduce, that still counts as +done — note the conflict and finish. Reserve a failed status for when your own +changes break the build. Put a one-line summary of any conflict 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/skills/posthog-integration/build/description.md b/context/skills/posthog-integration/build/description.md index 3cd4be1d..dc21207c 100644 --- a/context/skills/posthog-integration/build/description.md +++ b/context/skills/posthog-integration/build/description.md @@ -1,7 +1,9 @@ -# Install and build +# Install, build, and review -Install the declared dependencies, then verify the project builds. Be quick and -decisive — this step must not spiral. +Install the declared dependencies, verify the project builds, then review the +whole integration. This is the last check before the report — it is where the +run either earns trust or loses it. Be quick and decisive; this step must not +spiral. ## Install @@ -22,6 +24,25 @@ 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. +## Review the integration + +Before you finish, review everything the earlier steps changed — the queue log's +handoffs name the files each one touched. This catches the things users complain +about most: + +- **It builds.** A clean build or typecheck is the goal. If it fails, say so + plainly in the handoff `conflict` — the exact failing command and why — and, if + the failure is pre-existing, that the integration did not cause it. A silent or + vague build failure is the worst outcome; a clearly-reported one is fine. +- **It matches the codebase.** The added PostHog code must read like the code + around it — import style, naming, quotes, indentation, and the framework's + idioms. Fix anything that looks foreign to the file it lives in. +- **Nothing was mangled.** Confirm each touched file still has its original code + intact next to the PostHog additions, and that no file unrelated to the + integration was edited. If a step deleted or rewrote code it shouldn't have, or + reformatted an untouched region, restore it. Flag anything you can't safely fix + in `conflict`. + ## Flag out-of-scope conflicts and move on Work only inside this project's own directory. Never read, search, or write From 662d92ddfafdae6ed3314d7cb03bd76f75b63d87 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 14 Jul 2026 17:44:07 -0400 Subject: [PATCH 26/38] feat(agents): pull dashboard/notebook/report detail into orchestrator miniskills Extract the dashboard + insight examples, the notebook mirror (absent from the orchestrator until now), and the fuller pre-merge checklist out of the linear conclude step into miniskills the dashboard and report agents use; error-tracking and report run on luna (validated: same quality, ~half the cost/time). Co-Authored-By: Claude Opus 4.8 --- .../posthog-integration/error-tracking.md | 2 +- context/agents/posthog-integration/report.md | 9 ++- .../dashboard/description.md | 75 +++++++++++++++++-- .../posthog-integration/notebook/config.yaml | 11 +++ .../notebook/description.md | 23 ++++++ .../posthog-integration/report/description.md | 23 ++++-- 6 files changed, 123 insertions(+), 20 deletions(-) create mode 100644 context/skills/posthog-integration/notebook/config.yaml create mode 100644 context/skills/posthog-integration/notebook/description.md diff --git a/context/agents/posthog-integration/error-tracking.md b/context/agents/posthog-integration/error-tracking.md index 8e4900ce..0471acf4 100644 --- a/context/agents/posthog-integration/error-tracking.md +++ b/context/agents/posthog-integration/error-tracking.md @@ -2,7 +2,7 @@ type: error-tracking flow: posthog-integration label: Add error tracking -model: openai/gpt-5.6-terra +model: openai/gpt-5.6-luna skills: [posthog-integration-error-tracking-step] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/report.md b/context/agents/posthog-integration/report.md index 41392663..9227e5c7 100644 --- a/context/agents/posthog-integration/report.md +++ b/context/agents/posthog-integration/report.md @@ -2,8 +2,8 @@ type: report flow: posthog-integration label: Write the setup report -model: openai/gpt-5.6-terra -skills: [posthog-integration-report] +model: openai/gpt-5.6-luna +skills: [posthog-integration-report, posthog-integration-notebook] allowedTools: [Read, Write, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [dashboard] @@ -13,11 +13,12 @@ dependsOn: [dashboard] 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`). +`.posthog-events.json`), then mirror it into a shareable PostHog notebook. ## 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. +steps for the user. The report is also mirrored into a PostHog notebook whose URL +is emitted with the `[NOTEBOOK_URL]` marker. diff --git a/context/skills/posthog-integration/dashboard/description.md b/context/skills/posthog-integration/dashboard/description.md index 71e580c5..a895a301 100644 --- a/context/skills/posthog-integration/dashboard/description.md +++ b/context/skills/posthog-integration/dashboard/description.md @@ -1,11 +1,72 @@ # 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. +Create a live PostHog dashboard named `Analytics basics (wizard)` from the events +this integration instrumented, then populate it with up to five insights — lead +with the business-critical views: conversion funnels, activation, and churn +signals. Use the exact event names from the capture step's handoff; never invent +events that were not instrumented. Keep the `(wizard)` tag with that exact casing +so a search for `(wizard)` surfaces every wizard-created artifact. -- 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. +Everything here goes through `posthog_exec` (`call `). -Hand off the dashboard URL so the report can link to it. +## Create the dashboard, then attach insights + +Create the parent dashboard first with `dashboard-create`, capture its returned +`id`, then attach every insight to it via `dashboards: []`: + +```json +{ "name": "Analytics basics (wizard)", "description": "Key views for the events instrumented by the PostHog wizard.", "tags": ["wizard"] } +``` + +For `insight-create`, use these known-good query shapes — they are verified +against the MCP schema, and the common variations around them are rejected. + +A trends insight with a breakdown (breakdowns go in `breakdownFilter.breakdowns`, +an array — there is NO top-level `breakdown` field on `TrendsQuery`): + +```json +{ + "name": "Signups by plan (wizard)", + "dashboards": [], + "query": { "kind": "InsightVizNode", "source": { + "kind": "TrendsQuery", + "series": [{ "kind": "EventsNode", "event": "user_signed_up", "math": "total" }], + "interval": "day", + "dateRange": { "date_from": "-30d" }, + "breakdownFilter": { "breakdowns": [{ "type": "event", "property": "plan" }] }, + "trendsFilter": { "display": "ActionsBar" } + }} +} +``` + +A conversion funnel (window fields are camelCase and live INSIDE `funnelsFilter`, +not at the top level of `FunnelsQuery`, and not snake_case): + +```json +{ + "name": "Signup funnel (wizard)", + "dashboards": [], + "query": { "kind": "InsightVizNode", "source": { + "kind": "FunnelsQuery", + "series": [ + { "kind": "EventsNode", "event": "page_viewed" }, + { "kind": "EventsNode", "event": "user_signed_up" } + ], + "dateRange": { "date_from": "-30d" }, + "funnelsFilter": { "funnelVizType": "steps", "funnelOrderType": "ordered", "funnelWindowInterval": 14, "funnelWindowIntervalUnit": "day" } + }} +} +``` + +Valid `trendsFilter.display` values: `ActionsLineGraph`, `ActionsBar`, +`ActionsAreaGraph`, `ActionsPie`, `ActionsStackedBar`, `BoldNumber`, +`ActionsTable`. Names like `ActionsBarChart`/`ActionsBarGraph` are rejected. If an +insight call is rejected, fix the payload against these examples rather than +retrying variations. + +## Hand off the dashboard + +Emit the dashboard URL on its own line in your final message with this exact +marker so the wizard surfaces it: `[DASHBOARD_URL] `. A URL only +in prose, without the marker, is dropped. Also record the dashboard URL in your +handoff so the report step can link it. diff --git a/context/skills/posthog-integration/notebook/config.yaml b/context/skills/posthog-integration/notebook/config.yaml new file mode 100644 index 00000000..35504077 --- /dev/null +++ b/context/skills/posthog-integration/notebook/config.yaml @@ -0,0 +1,11 @@ +type: docs-only +template: description.md +description: Mirror the setup report into a shareable PostHog notebook +tags: [orchestrator, notebook] +variants: + - id: all + display_name: PostHog notebook step + tags: [orchestrator, notebook] + docs_urls: [] +cli: + role: internal diff --git a/context/skills/posthog-integration/notebook/description.md b/context/skills/posthog-integration/notebook/description.md new file mode 100644 index 00000000..d289b222 --- /dev/null +++ b/context/skills/posthog-integration/notebook/description.md @@ -0,0 +1,23 @@ +# Mirror the report into a PostHog notebook + +Once `posthog-setup-report.md` exists, mirror it into a shareable PostHog notebook +so the user has an in-app copy to link and comment on. The notebook is an extra +copy, not a replacement — keep the local report file in place. + +Call `notebooks-create` through `posthog_exec` with a `title` (e.g. +`PostHog setup (wizard) – `) and `content` set to a single markdown +node that wraps the report verbatim: + +```json +{ + "title": "PostHog setup (wizard) – ", + "content": { "type": "doc", "content": [ + { "type": "ph-markdown-notebook", "attrs": { "nodeId": "markdown-notebook-v2", "markdown": "" } } + ]} +} +``` + +Take the `short_id` from the response, build the URL as +`/project//notebooks/`, and emit it on its own line in +your final message with this exact marker so the wizard surfaces it: +`[NOTEBOOK_URL] `. A URL only in prose, without the marker, is dropped. diff --git a/context/skills/posthog-integration/report/description.md b/context/skills/posthog-integration/report/description.md index 4312fccd..197d9978 100644 --- a/context/skills/posthog-integration/report/description.md +++ b/context/skills/posthog-integration/report/description.md @@ -24,14 +24,21 @@ Include: - 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: +End with a "Before you merge" checklist as GitHub-style checkboxes (`- [ ] …`), +including only the items that apply to what was set up — judge each against the +code changed this run and drop the ones that don't fit: -- 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. +- Always: run a full production build (the wizard only verified the files it + touched) and fix any lint or type errors the generated code introduced. +- Always: run the test suite — instrumented call sites may need updated mocks or + fixtures. +- If env vars were added: their exact names are in `.env.example` and any + monorepo/bootstrap scripts, and set in the deploy environments, not just locally. +- If the app ships minified browser bundles: wire source-map upload into CI so + production stack traces de-minify — call it out with the docs link. +- If LLM analytics was set up: trigger the instrumented call path and confirm + `$ai_generation` events appear in PostHog. +- If auth exists and identify was wired: the returning-visitor path also calls + identify, so returning sessions don't fragment onto anonymous distinct IDs. Keep it skimmable. This is the artifact the user opens after the run. From dfc4f0745c13d84ea44d41d8a032c4e0fc757a6e Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Tue, 14 Jul 2026 17:56:55 -0400 Subject: [PATCH 27/38] feat(agents): name model + effort per harness profile (pi/gpt, sdk/claude) Each orchestrator agent carries model_pi/effort_pi and model_sdk/effort_sdk so the flow benchmarks either provider; the pi/sdk mapping is intentionally not 1:1 (error-tracking and report are luna on pi but sonnet on sdk). Co-Authored-By: Claude Opus 4.8 --- context/agents/README.md | 9 ++++++++- context/agents/posthog-integration/build.md | 5 ++++- context/agents/posthog-integration/capture.md | 5 ++++- context/agents/posthog-integration/dashboard.md | 5 ++++- context/agents/posthog-integration/error-tracking.md | 5 ++++- context/agents/posthog-integration/identify.md | 5 ++++- context/agents/posthog-integration/init.md | 4 +++- context/agents/posthog-integration/install.md | 4 +++- context/agents/posthog-integration/integrate-posthog.md | 5 ++++- context/agents/posthog-integration/report.md | 5 ++++- 10 files changed, 42 insertions(+), 10 deletions(-) diff --git a/context/agents/README.md b/context/agents/README.md index df45256f..3450bf84 100644 --- a/context/agents/README.md +++ b/context/agents/README.md @@ -22,11 +22,18 @@ so a prompt never restates them. Frontmatter stays flat: scalars and inline This README is documentation, not data: the build serves every other `.md` under a flow folder as an agent prompt. +Each agent names its model per harness profile — `model_pi`/`effort_pi` for the +gpt (pi) run and `model_sdk`/`effort_sdk` for the anthropic (sdk) run — so the +same flow benchmarks either provider. The mapping is not 1:1: a light task can be +luna on pi but sonnet on sdk. Effort is optional and overrides the model default. + ```markdown --- type: example flow: my-flow -model: claude-haiku-4-5-20251001 +model_pi: openai/gpt-5.6-luna +effort_pi: low +model_sdk: claude-haiku-4-5-20251001 skills: [] allowedTools: [Read, Glob, Grep] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/build.md b/context/agents/posthog-integration/build.md index f836e13f..1666074d 100644 --- a/context/agents/posthog-integration/build.md +++ b/context/agents/posthog-integration/build.md @@ -2,7 +2,10 @@ type: build flow: posthog-integration label: Build and review the integration -model: openai/gpt-5.6-terra +model_pi: openai/gpt-5.6-terra +effort_pi: medium +model_sdk: claude-sonnet-4-6 +effort_sdk: high skills: [posthog-integration-build] allowedTools: [Read, Edit, Glob, Grep, Bash] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/capture.md b/context/agents/posthog-integration/capture.md index 236d1d38..391b6b1e 100644 --- a/context/agents/posthog-integration/capture.md +++ b/context/agents/posthog-integration/capture.md @@ -2,7 +2,10 @@ type: capture flow: posthog-integration label: Capture events -model: openai/gpt-5.6-terra +model_pi: openai/gpt-5.6-terra +effort_pi: medium +model_sdk: claude-sonnet-4-6 +effort_sdk: high skills: [posthog-integration-capture] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/dashboard.md b/context/agents/posthog-integration/dashboard.md index b0a99c97..367796b4 100644 --- a/context/agents/posthog-integration/dashboard.md +++ b/context/agents/posthog-integration/dashboard.md @@ -2,7 +2,10 @@ type: dashboard flow: posthog-integration label: Create a starter dashboard -model: openai/gpt-5.6-terra +model_pi: openai/gpt-5.6-terra +effort_pi: medium +model_sdk: claude-sonnet-4-6 +effort_sdk: high skills: [posthog-integration-dashboard] allowedTools: [Read, Glob, Grep] disallowedTools: [Write, Edit, Bash, enqueue_task] diff --git a/context/agents/posthog-integration/error-tracking.md b/context/agents/posthog-integration/error-tracking.md index 0471acf4..b73d7a80 100644 --- a/context/agents/posthog-integration/error-tracking.md +++ b/context/agents/posthog-integration/error-tracking.md @@ -2,7 +2,10 @@ type: error-tracking flow: posthog-integration label: Add error tracking -model: openai/gpt-5.6-luna +model_pi: openai/gpt-5.6-luna +effort_pi: low +model_sdk: claude-sonnet-4-6 +effort_sdk: high skills: [posthog-integration-error-tracking-step] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/identify.md b/context/agents/posthog-integration/identify.md index c7297e5d..36ef3f6b 100644 --- a/context/agents/posthog-integration/identify.md +++ b/context/agents/posthog-integration/identify.md @@ -2,7 +2,10 @@ type: identify flow: posthog-integration label: Wire user identification -model: openai/gpt-5.6-terra +model_pi: openai/gpt-5.6-terra +effort_pi: medium +model_sdk: claude-sonnet-4-6 +effort_sdk: high skills: [posthog-integration-identify] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/init.md b/context/agents/posthog-integration/init.md index c3aa1727..c50d45e3 100644 --- a/context/agents/posthog-integration/init.md +++ b/context/agents/posthog-integration/init.md @@ -2,7 +2,9 @@ type: init flow: posthog-integration label: Set up PostHog initialization -model: openai/gpt-5.6-luna +model_pi: openai/gpt-5.6-luna +effort_pi: low +model_sdk: claude-haiku-4-5-20251001 skills: [posthog-integration-init] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/install.md b/context/agents/posthog-integration/install.md index 283cee8c..6e40f9ce 100644 --- a/context/agents/posthog-integration/install.md +++ b/context/agents/posthog-integration/install.md @@ -2,7 +2,9 @@ type: install flow: posthog-integration label: Add the PostHog SDK to the manifest -model: openai/gpt-5.6-luna +model_pi: openai/gpt-5.6-luna +effort_pi: low +model_sdk: claude-haiku-4-5-20251001 skills: [posthog-integration-install] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] diff --git a/context/agents/posthog-integration/integrate-posthog.md b/context/agents/posthog-integration/integrate-posthog.md index f6662144..e9b98866 100644 --- a/context/agents/posthog-integration/integrate-posthog.md +++ b/context/agents/posthog-integration/integrate-posthog.md @@ -2,7 +2,10 @@ type: integrate-posthog flow: posthog-integration seed: true -model: openai/gpt-5.6-terra +model_pi: openai/gpt-5.6-terra +effort_pi: medium +model_sdk: claude-sonnet-4-6 +effort_sdk: high skills: [] allowedTools: [Read, Glob, Grep] disallowedTools: [Write, Edit, Bash, complete_task] diff --git a/context/agents/posthog-integration/report.md b/context/agents/posthog-integration/report.md index 9227e5c7..2a032c0d 100644 --- a/context/agents/posthog-integration/report.md +++ b/context/agents/posthog-integration/report.md @@ -2,7 +2,10 @@ type: report flow: posthog-integration label: Write the setup report -model: openai/gpt-5.6-luna +model_pi: openai/gpt-5.6-luna +effort_pi: low +model_sdk: claude-sonnet-4-6 +effort_sdk: high skills: [posthog-integration-report, posthog-integration-notebook] allowedTools: [Read, Write, Glob, Grep] disallowedTools: [enqueue_task] From b0d4fd0488a9eaebaa2a98ef4edbef3ec09c68ab Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 15 Jul 2026 10:06:50 -0400 Subject: [PATCH 28/38] ci: raise the mcp-resources bundle limit to 8MB The orchestrator adds agents, step-skills, and dashboard/notebook examples that push the bundle past 5MB; raise the gate to fit. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 046cd338..bbd07bdb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,7 +46,7 @@ jobs: - name: Lint env var naming conventions run: bash scripts/lint-env-naming.sh - # No individual skill should be larger than 1MB, and the bundle should be less than 5MB. + # No individual skill should be larger than 1MB, and the bundle should be less than 8MB. - name: Check bundle and skill sizes run: | set -e @@ -61,8 +61,8 @@ jobs: bundle_bytes=$(stat -c%s "$BUNDLE" 2>/dev/null || stat -f%z "$BUNDLE") echo "skills-mcp-resources.zip size: ${bundle_bytes} bytes" - if [ "$bundle_bytes" -gt $((5 * 1024 * 1024)) ]; then - echo "::error::skills-mcp-resources.zip is larger than 5MB (current: ${bundle_bytes} bytes)" + if [ "$bundle_bytes" -gt $((8 * 1024 * 1024)) ]; then + echo "::error::skills-mcp-resources.zip is larger than 8MB (current: ${bundle_bytes} bytes)" exit 1 fi From d72f23c3ddec4fbaac7204cada4785211a2be6c4 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 15 Jul 2026 11:22:21 -0400 Subject: [PATCH 29/38] =?UTF-8?q?fix(agents):=20review=20fixes=20=E2=80=94?= =?UTF-8?q?=20declared=20framework=20identity,=20strict=20flow=20key,=20pu?= =?UTF-8?q?re=20variants=5Ffrom?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-ups from the review of #181: - skill-menu.json entries now carry `group` (hyphenated skill-id prefix), `framework` (the detection id a variant serves), and `default` (the variant a bare framework id resolves to when a family has several). Declared in the integration group's variant matrix and copied across by `variants_from`, so consumers resolve variants by exact match instead of reverse-engineering ids with alias tables and prefix guessing. Pairs with the wizard-side resolver change (PostHog/wizard PR on experiment/orchestrator-pi-runtask). - agent prompts must declare `flow:` — the build now rejects a missing key instead of only a contradicting one, since consumers filter prompts by it and a missing key built green here but silently dropped the prompt from the runtime registry. - `resolveVariantsFrom` is pure: it returns a resolved copy instead of mutating the config in place, which removes the `_variantsResolved` marker that existed to dodge the "variants or variants_from, not both" validation on re-expansion. Generated-By: PostHog Code Task-Id: fafc230d-6f14-4e4d-9462-0e7f18a1eec1 --- context/skills/integration/config.yaml | 45 ++++++++++++ scripts/lib/agent-generator.js | 14 +++- scripts/lib/build-phases.js | 13 +++- scripts/lib/skill-generator.js | 32 ++++++--- .../lib/tests/agent-generator-flow.test.js | 68 +++++++++++++++++++ scripts/lib/tests/skill-variants-from.test.js | 17 +++++ 6 files changed, 175 insertions(+), 14 deletions(-) create mode 100644 scripts/lib/tests/agent-generator-flow.test.js diff --git a/context/skills/integration/config.yaml b/context/skills/integration/config.yaml index 1dae71c4..71820372 100644 --- a/context/skills/integration/config.yaml +++ b/context/skills/integration/config.yaml @@ -1,4 +1,12 @@ # Integration skills - example-based (code + docs) +# +# `framework` names the detection id a variant serves (the id the wizard's +# detector emits, e.g. `rails`, `react-router`). It is emitted into +# skill-menu.json so consumers resolve a framework to a variant by exact +# match. When a family has several variants (app vs pages router), exactly +# one carries `default: true` — the one a bare framework id resolves to. +# Variants with no `framework` (e.g. react-vite, php) are only reachable by +# their full id. type: skill template: description.md description: PostHog integration for {display_name} applications @@ -6,6 +14,8 @@ shared_docs: - https://posthog.com/docs/getting-started/identify-users.md variants: - id: nextjs-app-router + framework: nextjs + default: true example_paths: example-apps/next-app-router display_name: Next.js App Router tags: [nextjs, react, ssr, app-router, javascript, javascript_web, javascript_node] @@ -13,6 +23,7 @@ variants: - https://posthog.com/docs/libraries/next-js.md - id: nextjs-pages-router + framework: nextjs example_paths: example-apps/next-pages-router display_name: Next.js Pages Router tags: [nextjs, react, ssr, pages-router, javascript, javascript_web, javascript_node] @@ -20,6 +31,8 @@ variants: - https://posthog.com/docs/libraries/next-js.md - id: react-react-router-6 + framework: react-router + default: true example_paths: example-apps/react-react-router-6 display_name: React Router v6 tags: [react, react-router, v6, spa, javascript, javascript_web] @@ -27,6 +40,7 @@ variants: - https://posthog.com/docs/libraries/react-router/react-router-v6.md - id: react-react-router-7-framework + framework: react-router example_paths: example-apps/react-react-router-7-framework display_name: React Router v7 - Framework mode tags: [react, react-router, v7, framework, ssr, javascript, javascript_node, javascript_web] @@ -34,6 +48,7 @@ variants: - https://posthog.com/docs/libraries/react-router/react-router-v7-framework-mode.md - id: react-react-router-7-data + framework: react-router example_paths: example-apps/react-react-router-7-data display_name: React Router v7 - Data mode tags: [react, react-router, v7, data, spa, javascript, javascript_web] @@ -41,6 +56,7 @@ variants: - https://posthog.com/docs/libraries/react-router/react-router-v7-data-mode.md - id: react-react-router-7-declarative + framework: react-router example_paths: example-apps/react-react-router-7-declarative display_name: React Router v7 - Declarative mode tags: [react, react-router, v7, declarative, spa, javascript, javascript_web] @@ -56,6 +72,8 @@ variants: - https://posthog.com/docs/libraries/react.md - id: nuxt-3-6 + framework: nuxt + default: true example_paths: example-apps/nuxt-3-6 display_name: Nuxt 3.6 description: PostHog integration for Nuxt versions 3.0 to 3.6 @@ -64,6 +82,7 @@ variants: - https://posthog.com/docs/libraries/nuxt-js-3-6.md - id: nuxt-4 + framework: nuxt example_paths: example-apps/nuxt-4 display_name: Nuxt 4 description: PostHog integration for Nuxt 4 applications @@ -72,6 +91,7 @@ variants: - https://posthog.com/docs/libraries/nuxt-js.md - id: vue-3 + framework: vue example_paths: example-apps/vue-3 display_name: Vue 3 description: PostHog integration for Vue 3 applications @@ -80,6 +100,7 @@ variants: - https://posthog.com/docs/libraries/vue-js.md - id: django + framework: django example_paths: example-apps/django display_name: Django tags: [django, python] @@ -87,6 +108,7 @@ variants: - https://posthog.com/docs/libraries/django.md - id: flask + framework: flask example_paths: example-apps/flask display_name: Flask tags: [flask, python] @@ -94,6 +116,7 @@ variants: - https://posthog.com/docs/libraries/flask.md - id: fastapi + framework: fastapi example_paths: example-apps/fastapi display_name: FastAPI description: PostHog integration for FastAPI applications @@ -102,6 +125,7 @@ variants: - https://posthog.com/docs/libraries/python.md - id: react-tanstack-router-file-based + framework: tanstack-router example_paths: example-apps/react-tanstack-router-file-based display_name: React with TanStack Router (file-based) description: PostHog integration for React applications using TanStack Router with file-based routing @@ -110,6 +134,8 @@ variants: - https://posthog.com/docs/libraries/tanstack-start.md - id: react-tanstack-router-code-based + framework: tanstack-router + default: true example_paths: example-apps/react-tanstack-router-code-based display_name: React with TanStack Router (code-based) description: PostHog integration for React applications using TanStack Router with code-based routing @@ -118,6 +144,7 @@ variants: - https://posthog.com/docs/libraries/tanstack-start.md - id: tanstack-start + framework: tanstack-start example_paths: example-apps/tanstack-start display_name: TanStack Start description: PostHog integration for TanStack Start full-stack applications @@ -126,6 +153,7 @@ variants: - https://posthog.com/docs/libraries/tanstack-start.md - id: laravel + framework: laravel example_paths: example-apps/laravel display_name: Laravel tags: [laravel, php] @@ -141,6 +169,7 @@ variants: - https://posthog.com/docs/libraries/php.md - id: ruby-on-rails + framework: rails example_paths: example-apps/ruby-on-rails display_name: Ruby on Rails tags: [ruby-on-rails, ruby] @@ -149,6 +178,7 @@ variants: - https://posthog.com/docs/libraries/ruby.md - id: android + framework: android example_paths: example-apps/android display_name: Android description: PostHog integration for Android applications @@ -157,6 +187,7 @@ variants: - https://posthog.com/docs/libraries/android.md - id: sveltekit + framework: sveltekit example_paths: example-apps/sveltekit display_name: SvelteKit description: PostHog integration for SvelteKit applications @@ -166,6 +197,7 @@ variants: # Language fallback skills, used when no specific framework is detected - id: python + framework: python example_paths: example-apps/python display_name: Python description: PostHog integration for any Python application using the Python SDK @@ -175,6 +207,7 @@ variants: - https://posthog.com/docs/references/posthog-python.md - id: javascript_node + framework: javascript_node example_path: example-apps/javascript-node display_name: JavaScript Node description: PostHog integration for server-side Node.js applications using posthog-node @@ -184,6 +217,7 @@ variants: - https://posthog.com/docs/references/posthog-node.md - id: javascript_web + framework: javascript_web example_path: example-apps/javascript-web display_name: JavaScript Web description: PostHog integration for client-side web JavaScript applications using posthog-js @@ -193,6 +227,7 @@ variants: - https://posthog.com/docs/references/posthog-js.md - id: ruby + framework: ruby example_paths: example-apps/ruby display_name: Ruby description: PostHog integration for any Ruby application using the Ruby SDK @@ -217,6 +252,7 @@ variants: - https://posthog.com/docs/libraries/go.md - id: swift + framework: swift example_paths: - example-apps/swift - example-apps/swift-xcodegen @@ -237,6 +273,8 @@ variants: - https://posthog.com/docs/libraries/flutter.md - id: react-native + framework: react-native + default: true example_paths: example-apps/react-native display_name: React Native description: PostHog integration for React Native applications @@ -245,6 +283,7 @@ variants: - https://posthog.com/docs/libraries/react-native.md - id: expo + framework: react-native example_paths: example-apps/expo display_name: Expo description: PostHog integration for Expo applications @@ -253,6 +292,7 @@ variants: - https://posthog.com/docs/libraries/react-native.md - id: astro-static + framework: astro example_paths: example-apps/astro-static display_name: Astro (Static) description: PostHog integration for static Astro sites using SSG @@ -261,6 +301,7 @@ variants: - https://posthog.com/docs/libraries/astro.md - id: astro-view-transitions + framework: astro example_paths: example-apps/astro-view-transitions display_name: Astro (View Transitions) description: PostHog integration for Astro with ClientRouter view transitions @@ -269,6 +310,7 @@ variants: - https://posthog.com/docs/libraries/astro.md - id: astro-ssr + framework: astro example_paths: example-apps/astro-ssr display_name: Astro (SSR) description: PostHog integration for server-rendered Astro applications with API routes @@ -277,6 +319,8 @@ variants: - https://posthog.com/docs/libraries/astro.md - id: astro-hybrid + framework: astro + default: true example_paths: example-apps/astro-hybrid display_name: Astro (Hybrid) description: PostHog integration for Astro hybrid rendering with both static and server-rendered pages @@ -285,6 +329,7 @@ variants: - https://posthog.com/docs/libraries/astro.md - id: angular + framework: angular example_paths: example-apps/angular display_name: Angular description: PostHog integration for Angular applications diff --git a/scripts/lib/agent-generator.js b/scripts/lib/agent-generator.js index 10689301..0de836e3 100644 --- a/scripts/lib/agent-generator.js +++ b/scripts/lib/agent-generator.js @@ -46,14 +46,22 @@ export function loadAgentEntries(agentsSourceDir) { } /** - * A prompt's frontmatter `flow:` must match its folder — the folder is the - * registry scope, the frontmatter keeps the file self-describing on disk. + * A prompt's frontmatter `flow:` must be present and match its folder — the + * folder is the registry scope, the frontmatter keeps the file + * self-describing on disk. Absence is an error, not a pass: consumers filter + * prompts by the frontmatter flow, so a missing key would build fine here and + * then silently drop the prompt from the registry at runtime. */ function assertFlowMatches(sourcePath, flow) { const text = fs.readFileSync(sourcePath, 'utf8'); const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---/); const declared = match?.[1].match(/^flow:\s*(.+?)\s*$/m)?.[1]; - if (declared && declared !== flow) { + if (!declared) { + throw new Error( + `Agent prompt ${sourcePath} is missing the "flow:" frontmatter key — declare flow: ${flow}`, + ); + } + if (declared !== flow) { throw new Error( `Agent prompt ${sourcePath} declares flow "${declared}" but lives in agents/${flow}/`, ); diff --git a/scripts/lib/build-phases.js b/scripts/lib/build-phases.js index a52e08d8..30e59dd2 100644 --- a/scripts/lib/build-phases.js +++ b/scripts/lib/build-phases.js @@ -190,11 +190,20 @@ function writeManifestAndMenu({ allSkills, docContents, distDir, configDir, vers for (const skill of allSkills) { const cat = skill.group; if (!skillsByCategory[cat]) skillsByCategory[cat] = []; - skillsByCategory[cat].push({ + // `group` is the hyphenated skill-id prefix and `framework` the + // detection id a variant serves, so a consumer resolves a bare skill + // id + framework to a menu id by exact match instead of guessing from + // id prefixes. `default: true` marks the variant a bare framework id + // resolves to when a family has several (e.g. app vs pages router). + const entry = { id: skill.id, name: skill.name, + group: skill.group.replace(/\//g, '-'), downloadUrl: manifest.resources.find(r => r.id === skill.id)?.downloadUrl, - }); + }; + if (skill.framework) entry.framework = skill.framework; + if (skill.default) entry.default = true; + skillsByCategory[cat].push(entry); } // The CLI entries are the lookup table the wizard's runtime resolver uses diff --git a/scripts/lib/skill-generator.js b/scripts/lib/skill-generator.js index e67998b6..a06e9021 100644 --- a/scripts/lib/skill-generator.js +++ b/scripts/lib/skill-generator.js @@ -228,15 +228,20 @@ function normalizeExamplePaths(value) { /** * Resolve `variants_from` references: a group may borrow another group's * variant matrix instead of duplicating it. Only the framework identity comes - * across — id, display_name, tags, docs_urls — never example paths, templates, - * cli blocks, or shared docs, which stay the borrowing group's own concern. - * One level only; a source group must declare its variants literally. + * across — id, display_name, tags, docs_urls, framework, default — never + * example paths, templates, cli blocks, or shared docs, which stay the + * borrowing group's own concern. One level only; a source group must declare + * its variants literally. Returns a new config; the input is never mutated, + * so repeated expansion of the same config is naturally stable. */ function resolveVariantsFrom(config) { + const resolved = {}; for (const [key, group] of Object.entries(config)) { - if (!group.variants_from) continue; + if (!group.variants_from) { + resolved[key] = group; + continue; + } if (group.variants) { - if (group._variantsResolved) continue; throw new Error(`Skill group "${key}": declare either variants or variants_from, not both`); } const source = config[group.variants_from]; @@ -246,14 +251,17 @@ function resolveVariantsFrom(config) { if (source.variants_from) { throw new Error(`Skill group "${key}": variants_from cannot chain ("${group.variants_from}" also uses variants_from)`); } - group.variants = source.variants.map(v => { + const variants = source.variants.map(v => { const variant = { id: v.id, display_name: v.display_name }; if (v.tags) variant.tags = [...v.tags]; if (v.docs_urls) variant.docs_urls = [...v.docs_urls]; + if (v.framework) variant.framework = v.framework; + if (v.default) variant.default = v.default; return variant; }); - group._variantsResolved = true; + resolved[key] = { ...group, variants }; } + return resolved; } /** @@ -263,9 +271,9 @@ function resolveVariantsFrom(config) { */ function expandSkillGroups(config, configDir) { const skills = []; - resolveVariantsFrom(config); + const resolvedConfig = resolveVariantsFrom(config); - for (const [key, group] of Object.entries(config)) { + for (const [key, group] of Object.entries(resolvedConfig)) { if (key === 'shared_docs') continue; if (!group.variants) continue; @@ -796,6 +804,12 @@ function serializeSkill(s) { description: s.description, tags: s.tags || [], }; + if (s.framework) { + result.framework = s.framework; + } + if (s.default) { + result.default = true; + } if (s._cli) { result.cli = s._cli; } diff --git a/scripts/lib/tests/agent-generator-flow.test.js b/scripts/lib/tests/agent-generator-flow.test.js new file mode 100644 index 00000000..8e4e54d1 --- /dev/null +++ b/scripts/lib/tests/agent-generator-flow.test.js @@ -0,0 +1,68 @@ +import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { mkdirSync, writeFileSync, mkdtempSync, rmSync, readFileSync, existsSync } from 'fs'; +import { join } from 'path'; +import { tmpdir } from 'os'; + +import { buildAgents } from '../agent-generator.js'; + +const prompt = (frontmatter) => `---\n${frontmatter}\n---\n\n## Goal\n\nDo the thing.\n`; + +describe('buildAgents flow frontmatter', () => { + let tmpDir; + let configDir; + let distDir; + + beforeEach(() => { + tmpDir = mkdtempSync(join(tmpdir(), 'agents-test-')); + configDir = join(tmpDir, 'context'); + distDir = join(tmpDir, 'dist'); + mkdirSync(join(configDir, 'agents', 'my-flow'), { recursive: true }); + }); + + afterEach(() => rmSync(tmpDir, { recursive: true, force: true })); + + it('builds a prompt whose flow matches its folder', () => { + writeFileSync( + join(configDir, 'agents', 'my-flow', 'task.md'), + prompt('type: task\nflow: my-flow'), + ); + const { count } = buildAgents({ configDir, distDir, baseUrl: 'http://x' }); + expect(count).toBe(1); + const menu = JSON.parse(readFileSync(join(distDir, 'agents', 'agent-menu.json'), 'utf8')); + expect(menu.agents).toEqual([ + { id: 'task', flow: 'my-flow', downloadUrl: 'http://x/my-flow/task.md' }, + ]); + }); + + it('rejects a prompt missing the flow key — consumers filter by it', () => { + writeFileSync( + join(configDir, 'agents', 'my-flow', 'task.md'), + prompt('type: task'), + ); + expect(() => buildAgents({ configDir, distDir, baseUrl: 'http://x' })).toThrow( + /missing the "flow:" frontmatter key/, + ); + }); + + it('rejects a prompt whose flow contradicts its folder', () => { + writeFileSync( + join(configDir, 'agents', 'my-flow', 'task.md'), + prompt('type: task\nflow: other-flow'), + ); + expect(() => buildAgents({ configDir, distDir, baseUrl: 'http://x' })).toThrow( + /declares flow "other-flow"/, + ); + }); + + it('still ignores README.md files at both levels', () => { + writeFileSync(join(configDir, 'agents', 'README.md'), '# docs'); + writeFileSync(join(configDir, 'agents', 'my-flow', 'README.md'), '# docs'); + writeFileSync( + join(configDir, 'agents', 'my-flow', 'task.md'), + prompt('type: task\nflow: my-flow'), + ); + const { count } = buildAgents({ configDir, distDir, baseUrl: 'http://x' }); + expect(count).toBe(1); + expect(existsSync(join(distDir, 'agents', 'my-flow', 'README.md'))).toBe(false); + }); +}); diff --git a/scripts/lib/tests/skill-variants-from.test.js b/scripts/lib/tests/skill-variants-from.test.js index f3bcbd79..acf5d833 100644 --- a/scripts/lib/tests/skill-variants-from.test.js +++ b/scripts/lib/tests/skill-variants-from.test.js @@ -40,6 +40,8 @@ describe('variants_from', () => { { id: 'django', display_name: 'Django', + framework: 'django', + default: true, tags: ['django', 'python'], docs_urls: ['https://posthog.com/docs/libraries/django.md'], example_paths: 'example-apps/django', @@ -77,6 +79,21 @@ describe('variants_from', () => { expect(step._examplePaths).toEqual([]); }); + it('borrows framework and default so variant steps resolve like the source', () => { + const config = { integration: integrationGroup(), 'flow-x/install': borrowingGroup() }; + const skills = expandSkillGroups(config, tmpDir); + const step = skills.find(s => s.id === 'flow-x-install-django'); + expect(step.framework).toBe('django'); + expect(step.default).toBe(true); + }); + + it('does not mutate the input config', () => { + const config = { integration: integrationGroup(), 'flow-x/install': borrowingGroup() }; + expandSkillGroups(config, tmpDir); + expect(config['flow-x/install'].variants).toBeUndefined(); + expect(config['flow-x/install']._variantsResolved).toBeUndefined(); + }); + it('leaves the source group untouched', () => { const config = { integration: integrationGroup(), 'flow-x/install': borrowingGroup() }; const skills = expandSkillGroups(config, tmpDir); From 1d6c63b4b658f46b0623fc1beaae602261a9cf48 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 15 Jul 2026 11:34:17 -0400 Subject: [PATCH 30/38] chore(agents): trim review-fix comments to one-liners Generated-By: PostHog Code Task-Id: fafc230d-6f14-4e4d-9462-0e7f18a1eec1 --- context/skills/integration/config.yaml | 9 +-------- scripts/lib/agent-generator.js | 7 ++----- scripts/lib/build-phases.js | 6 +----- scripts/lib/skill-generator.js | 3 +-- 4 files changed, 5 insertions(+), 20 deletions(-) diff --git a/context/skills/integration/config.yaml b/context/skills/integration/config.yaml index 71820372..d676a1fd 100644 --- a/context/skills/integration/config.yaml +++ b/context/skills/integration/config.yaml @@ -1,12 +1,5 @@ # Integration skills - example-based (code + docs) -# -# `framework` names the detection id a variant serves (the id the wizard's -# detector emits, e.g. `rails`, `react-router`). It is emitted into -# skill-menu.json so consumers resolve a framework to a variant by exact -# match. When a family has several variants (app vs pages router), exactly -# one carries `default: true` — the one a bare framework id resolves to. -# Variants with no `framework` (e.g. react-vite, php) are only reachable by -# their full id. +# `framework` = the detection id a variant serves; `default: true` marks the family default. Both are emitted into skill-menu.json. type: skill template: description.md description: PostHog integration for {display_name} applications diff --git a/scripts/lib/agent-generator.js b/scripts/lib/agent-generator.js index 0de836e3..93e8aac3 100644 --- a/scripts/lib/agent-generator.js +++ b/scripts/lib/agent-generator.js @@ -46,11 +46,8 @@ export function loadAgentEntries(agentsSourceDir) { } /** - * A prompt's frontmatter `flow:` must be present and match its folder — the - * folder is the registry scope, the frontmatter keeps the file - * self-describing on disk. Absence is an error, not a pass: consumers filter - * prompts by the frontmatter flow, so a missing key would build fine here and - * then silently drop the prompt from the registry at runtime. + * A prompt's frontmatter `flow:` must be present and match its folder — + * consumers filter by it, so a missing key would silently drop the prompt. */ function assertFlowMatches(sourcePath, flow) { const text = fs.readFileSync(sourcePath, 'utf8'); diff --git a/scripts/lib/build-phases.js b/scripts/lib/build-phases.js index 30e59dd2..d65370de 100644 --- a/scripts/lib/build-phases.js +++ b/scripts/lib/build-phases.js @@ -190,11 +190,7 @@ function writeManifestAndMenu({ allSkills, docContents, distDir, configDir, vers for (const skill of allSkills) { const cat = skill.group; if (!skillsByCategory[cat]) skillsByCategory[cat] = []; - // `group` is the hyphenated skill-id prefix and `framework` the - // detection id a variant serves, so a consumer resolves a bare skill - // id + framework to a menu id by exact match instead of guessing from - // id prefixes. `default: true` marks the variant a bare framework id - // resolves to when a family has several (e.g. app vs pages router). + // group/framework/default let consumers resolve a bare skill id + framework by exact match. const entry = { id: skill.id, name: skill.name, diff --git a/scripts/lib/skill-generator.js b/scripts/lib/skill-generator.js index a06e9021..5cf53d13 100644 --- a/scripts/lib/skill-generator.js +++ b/scripts/lib/skill-generator.js @@ -231,8 +231,7 @@ function normalizeExamplePaths(value) { * across — id, display_name, tags, docs_urls, framework, default — never * example paths, templates, cli blocks, or shared docs, which stay the * borrowing group's own concern. One level only; a source group must declare - * its variants literally. Returns a new config; the input is never mutated, - * so repeated expansion of the same config is naturally stable. + * its variants literally. Pure — returns a new config, never mutates the input. */ function resolveVariantsFrom(config) { const resolved = {}; From 6eeba8eb8cc559ef2f86d9674ed97328eaa85341 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 15 Jul 2026 12:43:48 -0400 Subject: [PATCH 31/38] refactor: drop the stale variants_from key from resolved groups (/simplify) Generated-By: PostHog Code Task-Id: fafc230d-6f14-4e4d-9462-0e7f18a1eec1 --- scripts/lib/skill-generator.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/lib/skill-generator.js b/scripts/lib/skill-generator.js index 5cf53d13..86b8b825 100644 --- a/scripts/lib/skill-generator.js +++ b/scripts/lib/skill-generator.js @@ -258,7 +258,9 @@ function resolveVariantsFrom(config) { if (v.default) variant.default = v.default; return variant; }); - resolved[key] = { ...group, variants }; + // Drop the reference key — the resolved copy declares variants literally. + const { variants_from: _from, ...rest } = group; + resolved[key] = { ...rest, variants }; } return resolved; } From 23276d8e58a3c5d993c7232a31dceb7e18994f11 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 15 Jul 2026 18:03:51 -0400 Subject: [PATCH 32/38] feat: rename posthog-integration flow to integration-v2 + init-key commandment Renames the orchestrator agents/ and skills/ flow to integration-v2, and adds a javascript_web commandment to pass the project key to init() straight from env rather than defaulting to an empty string. Co-Authored-By: Claude Opus 4.8 --- context/agents/{posthog-integration => integration-v2}/build.md | 0 .../agents/{posthog-integration => integration-v2}/capture.md | 0 .../agents/{posthog-integration => integration-v2}/dashboard.md | 0 .../{posthog-integration => integration-v2}/error-tracking.md | 0 .../agents/{posthog-integration => integration-v2}/identify.md | 0 context/agents/{posthog-integration => integration-v2}/init.md | 0 .../agents/{posthog-integration => integration-v2}/install.md | 0 .../{posthog-integration => integration-v2}/integrate-posthog.md | 0 context/agents/{posthog-integration => integration-v2}/report.md | 0 context/commandments.yaml | 1 + .../{posthog-integration => integration-v2}/build/config.yaml | 0 .../{posthog-integration => integration-v2}/build/description.md | 0 .../{posthog-integration => integration-v2}/capture/config.yaml | 0 .../capture/description.md | 0 .../dashboard/config.yaml | 0 .../dashboard/description.md | 0 .../error-tracking-step/config.yaml | 0 .../error-tracking-step/description.md | 0 .../{posthog-integration => integration-v2}/identify/config.yaml | 0 .../identify/description.md | 0 .../{posthog-integration => integration-v2}/init/config.yaml | 0 .../{posthog-integration => integration-v2}/init/description.md | 0 .../{posthog-integration => integration-v2}/install/config.yaml | 0 .../install/description.md | 0 .../{posthog-integration => integration-v2}/notebook/config.yaml | 0 .../notebook/description.md | 0 .../{posthog-integration => integration-v2}/report/config.yaml | 0 .../report/description.md | 0 28 files changed, 1 insertion(+) rename context/agents/{posthog-integration => integration-v2}/build.md (100%) rename context/agents/{posthog-integration => integration-v2}/capture.md (100%) rename context/agents/{posthog-integration => integration-v2}/dashboard.md (100%) rename context/agents/{posthog-integration => integration-v2}/error-tracking.md (100%) rename context/agents/{posthog-integration => integration-v2}/identify.md (100%) rename context/agents/{posthog-integration => integration-v2}/init.md (100%) rename context/agents/{posthog-integration => integration-v2}/install.md (100%) rename context/agents/{posthog-integration => integration-v2}/integrate-posthog.md (100%) rename context/agents/{posthog-integration => integration-v2}/report.md (100%) rename context/skills/{posthog-integration => integration-v2}/build/config.yaml (100%) rename context/skills/{posthog-integration => integration-v2}/build/description.md (100%) rename context/skills/{posthog-integration => integration-v2}/capture/config.yaml (100%) rename context/skills/{posthog-integration => integration-v2}/capture/description.md (100%) rename context/skills/{posthog-integration => integration-v2}/dashboard/config.yaml (100%) rename context/skills/{posthog-integration => integration-v2}/dashboard/description.md (100%) rename context/skills/{posthog-integration => integration-v2}/error-tracking-step/config.yaml (100%) rename context/skills/{posthog-integration => integration-v2}/error-tracking-step/description.md (100%) rename context/skills/{posthog-integration => integration-v2}/identify/config.yaml (100%) rename context/skills/{posthog-integration => integration-v2}/identify/description.md (100%) rename context/skills/{posthog-integration => integration-v2}/init/config.yaml (100%) rename context/skills/{posthog-integration => integration-v2}/init/description.md (100%) rename context/skills/{posthog-integration => integration-v2}/install/config.yaml (100%) rename context/skills/{posthog-integration => integration-v2}/install/description.md (100%) rename context/skills/{posthog-integration => integration-v2}/notebook/config.yaml (100%) rename context/skills/{posthog-integration => integration-v2}/notebook/description.md (100%) rename context/skills/{posthog-integration => integration-v2}/report/config.yaml (100%) rename context/skills/{posthog-integration => integration-v2}/report/description.md (100%) diff --git a/context/agents/posthog-integration/build.md b/context/agents/integration-v2/build.md similarity index 100% rename from context/agents/posthog-integration/build.md rename to context/agents/integration-v2/build.md diff --git a/context/agents/posthog-integration/capture.md b/context/agents/integration-v2/capture.md similarity index 100% rename from context/agents/posthog-integration/capture.md rename to context/agents/integration-v2/capture.md diff --git a/context/agents/posthog-integration/dashboard.md b/context/agents/integration-v2/dashboard.md similarity index 100% rename from context/agents/posthog-integration/dashboard.md rename to context/agents/integration-v2/dashboard.md diff --git a/context/agents/posthog-integration/error-tracking.md b/context/agents/integration-v2/error-tracking.md similarity index 100% rename from context/agents/posthog-integration/error-tracking.md rename to context/agents/integration-v2/error-tracking.md diff --git a/context/agents/posthog-integration/identify.md b/context/agents/integration-v2/identify.md similarity index 100% rename from context/agents/posthog-integration/identify.md rename to context/agents/integration-v2/identify.md diff --git a/context/agents/posthog-integration/init.md b/context/agents/integration-v2/init.md similarity index 100% rename from context/agents/posthog-integration/init.md rename to context/agents/integration-v2/init.md diff --git a/context/agents/posthog-integration/install.md b/context/agents/integration-v2/install.md similarity index 100% rename from context/agents/posthog-integration/install.md rename to context/agents/integration-v2/install.md diff --git a/context/agents/posthog-integration/integrate-posthog.md b/context/agents/integration-v2/integrate-posthog.md similarity index 100% rename from context/agents/posthog-integration/integrate-posthog.md rename to context/agents/integration-v2/integrate-posthog.md diff --git a/context/agents/posthog-integration/report.md b/context/agents/integration-v2/report.md similarity index 100% rename from context/agents/posthog-integration/report.md rename to context/agents/integration-v2/report.md diff --git a/context/commandments.yaml b/context/commandments.yaml index 971780d5..75fa27f4 100644 --- a/context/commandments.yaml +++ b/context/commandments.yaml @@ -44,6 +44,7 @@ commandments: - When a reverse proxy is configured, both /static/* AND /array/* must route to the assets origin (us-assets.i.posthog.com or eu-assets.i.posthog.com). - posthog-js is the JavaScript SDK package name - posthog.init() MUST be called before any other PostHog methods (capture, identify, etc.) + - Pass the project API key to posthog.init() straight from its env var — do NOT default it to an empty string or placeholder when missing; a missing key must fail visibly rather than silently disabling analytics (a default host URL is fine) - posthog-js is browser-only — do NOT import it in Node.js or server-side contexts (use posthog-node instead) - Autocapture is ON by default with posthog-js (tracks clicks, form submissions, pageviews). Keep autocapture enabled unless the user explicitly asks to turn it off. - NEVER send PII in posthog.capture() event properties — no emails, full names, phone numbers, physical addresses, IP addresses, or user-generated content diff --git a/context/skills/posthog-integration/build/config.yaml b/context/skills/integration-v2/build/config.yaml similarity index 100% rename from context/skills/posthog-integration/build/config.yaml rename to context/skills/integration-v2/build/config.yaml diff --git a/context/skills/posthog-integration/build/description.md b/context/skills/integration-v2/build/description.md similarity index 100% rename from context/skills/posthog-integration/build/description.md rename to context/skills/integration-v2/build/description.md diff --git a/context/skills/posthog-integration/capture/config.yaml b/context/skills/integration-v2/capture/config.yaml similarity index 100% rename from context/skills/posthog-integration/capture/config.yaml rename to context/skills/integration-v2/capture/config.yaml diff --git a/context/skills/posthog-integration/capture/description.md b/context/skills/integration-v2/capture/description.md similarity index 100% rename from context/skills/posthog-integration/capture/description.md rename to context/skills/integration-v2/capture/description.md diff --git a/context/skills/posthog-integration/dashboard/config.yaml b/context/skills/integration-v2/dashboard/config.yaml similarity index 100% rename from context/skills/posthog-integration/dashboard/config.yaml rename to context/skills/integration-v2/dashboard/config.yaml diff --git a/context/skills/posthog-integration/dashboard/description.md b/context/skills/integration-v2/dashboard/description.md similarity index 100% rename from context/skills/posthog-integration/dashboard/description.md rename to context/skills/integration-v2/dashboard/description.md diff --git a/context/skills/posthog-integration/error-tracking-step/config.yaml b/context/skills/integration-v2/error-tracking-step/config.yaml similarity index 100% rename from context/skills/posthog-integration/error-tracking-step/config.yaml rename to context/skills/integration-v2/error-tracking-step/config.yaml diff --git a/context/skills/posthog-integration/error-tracking-step/description.md b/context/skills/integration-v2/error-tracking-step/description.md similarity index 100% rename from context/skills/posthog-integration/error-tracking-step/description.md rename to context/skills/integration-v2/error-tracking-step/description.md diff --git a/context/skills/posthog-integration/identify/config.yaml b/context/skills/integration-v2/identify/config.yaml similarity index 100% rename from context/skills/posthog-integration/identify/config.yaml rename to context/skills/integration-v2/identify/config.yaml diff --git a/context/skills/posthog-integration/identify/description.md b/context/skills/integration-v2/identify/description.md similarity index 100% rename from context/skills/posthog-integration/identify/description.md rename to context/skills/integration-v2/identify/description.md diff --git a/context/skills/posthog-integration/init/config.yaml b/context/skills/integration-v2/init/config.yaml similarity index 100% rename from context/skills/posthog-integration/init/config.yaml rename to context/skills/integration-v2/init/config.yaml diff --git a/context/skills/posthog-integration/init/description.md b/context/skills/integration-v2/init/description.md similarity index 100% rename from context/skills/posthog-integration/init/description.md rename to context/skills/integration-v2/init/description.md diff --git a/context/skills/posthog-integration/install/config.yaml b/context/skills/integration-v2/install/config.yaml similarity index 100% rename from context/skills/posthog-integration/install/config.yaml rename to context/skills/integration-v2/install/config.yaml diff --git a/context/skills/posthog-integration/install/description.md b/context/skills/integration-v2/install/description.md similarity index 100% rename from context/skills/posthog-integration/install/description.md rename to context/skills/integration-v2/install/description.md diff --git a/context/skills/posthog-integration/notebook/config.yaml b/context/skills/integration-v2/notebook/config.yaml similarity index 100% rename from context/skills/posthog-integration/notebook/config.yaml rename to context/skills/integration-v2/notebook/config.yaml diff --git a/context/skills/posthog-integration/notebook/description.md b/context/skills/integration-v2/notebook/description.md similarity index 100% rename from context/skills/posthog-integration/notebook/description.md rename to context/skills/integration-v2/notebook/description.md diff --git a/context/skills/posthog-integration/report/config.yaml b/context/skills/integration-v2/report/config.yaml similarity index 100% rename from context/skills/posthog-integration/report/config.yaml rename to context/skills/integration-v2/report/config.yaml diff --git a/context/skills/posthog-integration/report/description.md b/context/skills/integration-v2/report/description.md similarity index 100% rename from context/skills/posthog-integration/report/description.md rename to context/skills/integration-v2/report/description.md From b528c4fcada6243c6a838f68e3b0bc2f173a8477 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 15 Jul 2026 18:38:54 -0400 Subject: [PATCH 33/38] fix(commandments): android must not default the project key to empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors the iOS guidance for Android — the project token is a public client key safe to embed, so source it but never fall back to an empty string, which silently disables analytics (caught on a real Tusky run: getenv(...) ?: ""). Co-Authored-By: Claude Opus 4.8 --- context/commandments.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/context/commandments.yaml b/context/commandments.yaml index 57cbd7b1..bf559b9b 100644 --- a/context/commandments.yaml +++ b/context/commandments.yaml @@ -278,6 +278,7 @@ commandments: - Adapt dependency configuration to the appropriate build.gradle(.kts) file according to the project gradle version - Call `PostHogAndroid.setup()` only once in the Application class's `onCreate()` method, so it's initialized as early as possible and only once. - Initialize PostHog in the Application class's `onCreate()` method + - The project token is a public client-side key safe to embed in the app. Source it (BuildConfig field, Gradle/local.properties) but do NOT default it to an empty string when absent — an empty key silently disables analytics; ensure a real value always ships in the build. - Ensure every activity has a `android:label` to accurately track screen views. kmp: From deece51b09346adab73f37a4c5294593478fe3c0 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 15 Jul 2026 18:44:51 -0400 Subject: [PATCH 34/38] fix(agents): commit integration-v2 flow + skill refs (CI build fix) The rename commit staged the directory move but not the frontmatter edits, so the committed agents still declared flow: posthog-integration in agents/integration-v2/, failing assertFlowMatches in CI. This commits the corrected flow + skill ids. Co-Authored-By: Claude Opus 4.8 --- context/agents/integration-v2/build.md | 4 ++-- context/agents/integration-v2/capture.md | 4 ++-- context/agents/integration-v2/dashboard.md | 4 ++-- context/agents/integration-v2/error-tracking.md | 4 ++-- context/agents/integration-v2/identify.md | 4 ++-- context/agents/integration-v2/init.md | 4 ++-- context/agents/integration-v2/install.md | 4 ++-- context/agents/integration-v2/integrate-posthog.md | 2 +- context/agents/integration-v2/report.md | 4 ++-- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/context/agents/integration-v2/build.md b/context/agents/integration-v2/build.md index 1666074d..69bc9e60 100644 --- a/context/agents/integration-v2/build.md +++ b/context/agents/integration-v2/build.md @@ -1,12 +1,12 @@ --- type: build -flow: posthog-integration +flow: integration-v2 label: Build and review the integration model_pi: openai/gpt-5.6-terra effort_pi: medium model_sdk: claude-sonnet-4-6 effort_sdk: high -skills: [posthog-integration-build] +skills: [integration-v2-build] allowedTools: [Read, Edit, Glob, Grep, Bash] disallowedTools: [enqueue_task] dependsOn: [install, init, identify, error-tracking, capture] diff --git a/context/agents/integration-v2/capture.md b/context/agents/integration-v2/capture.md index 391b6b1e..08b5cdd2 100644 --- a/context/agents/integration-v2/capture.md +++ b/context/agents/integration-v2/capture.md @@ -1,12 +1,12 @@ --- type: capture -flow: posthog-integration +flow: integration-v2 label: Capture events model_pi: openai/gpt-5.6-terra effort_pi: medium model_sdk: claude-sonnet-4-6 effort_sdk: high -skills: [posthog-integration-capture] +skills: [integration-v2-capture] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [install, init] diff --git a/context/agents/integration-v2/dashboard.md b/context/agents/integration-v2/dashboard.md index 367796b4..a3fd6de1 100644 --- a/context/agents/integration-v2/dashboard.md +++ b/context/agents/integration-v2/dashboard.md @@ -1,12 +1,12 @@ --- type: dashboard -flow: posthog-integration +flow: integration-v2 label: Create a starter dashboard model_pi: openai/gpt-5.6-terra effort_pi: medium model_sdk: claude-sonnet-4-6 effort_sdk: high -skills: [posthog-integration-dashboard] +skills: [integration-v2-dashboard] allowedTools: [Read, Glob, Grep] disallowedTools: [Write, Edit, Bash, enqueue_task] dependsOn: [build] diff --git a/context/agents/integration-v2/error-tracking.md b/context/agents/integration-v2/error-tracking.md index b73d7a80..93a7bcd9 100644 --- a/context/agents/integration-v2/error-tracking.md +++ b/context/agents/integration-v2/error-tracking.md @@ -1,12 +1,12 @@ --- type: error-tracking -flow: posthog-integration +flow: integration-v2 label: Add error tracking model_pi: openai/gpt-5.6-luna effort_pi: low model_sdk: claude-sonnet-4-6 effort_sdk: high -skills: [posthog-integration-error-tracking-step] +skills: [integration-v2-error-tracking-step] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [install, init] diff --git a/context/agents/integration-v2/identify.md b/context/agents/integration-v2/identify.md index 36ef3f6b..02eeb7c1 100644 --- a/context/agents/integration-v2/identify.md +++ b/context/agents/integration-v2/identify.md @@ -1,12 +1,12 @@ --- type: identify -flow: posthog-integration +flow: integration-v2 label: Wire user identification model_pi: openai/gpt-5.6-terra effort_pi: medium model_sdk: claude-sonnet-4-6 effort_sdk: high -skills: [posthog-integration-identify] +skills: [integration-v2-identify] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [install, init] diff --git a/context/agents/integration-v2/init.md b/context/agents/integration-v2/init.md index c50d45e3..3d4a67e3 100644 --- a/context/agents/integration-v2/init.md +++ b/context/agents/integration-v2/init.md @@ -1,11 +1,11 @@ --- type: init -flow: posthog-integration +flow: integration-v2 label: Set up PostHog initialization model_pi: openai/gpt-5.6-luna effort_pi: low model_sdk: claude-haiku-4-5-20251001 -skills: [posthog-integration-init] +skills: [integration-v2-init] allowedTools: [Read, Write, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [] diff --git a/context/agents/integration-v2/install.md b/context/agents/integration-v2/install.md index 6e40f9ce..92f1f8a3 100644 --- a/context/agents/integration-v2/install.md +++ b/context/agents/integration-v2/install.md @@ -1,11 +1,11 @@ --- type: install -flow: posthog-integration +flow: integration-v2 label: Add the PostHog SDK to the manifest model_pi: openai/gpt-5.6-luna effort_pi: low model_sdk: claude-haiku-4-5-20251001 -skills: [posthog-integration-install] +skills: [integration-v2-install] allowedTools: [Read, Edit, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [] diff --git a/context/agents/integration-v2/integrate-posthog.md b/context/agents/integration-v2/integrate-posthog.md index e9b98866..c14ce296 100644 --- a/context/agents/integration-v2/integrate-posthog.md +++ b/context/agents/integration-v2/integrate-posthog.md @@ -1,6 +1,6 @@ --- type: integrate-posthog -flow: posthog-integration +flow: integration-v2 seed: true model_pi: openai/gpt-5.6-terra effort_pi: medium diff --git a/context/agents/integration-v2/report.md b/context/agents/integration-v2/report.md index 2a032c0d..4bd58a3a 100644 --- a/context/agents/integration-v2/report.md +++ b/context/agents/integration-v2/report.md @@ -1,12 +1,12 @@ --- type: report -flow: posthog-integration +flow: integration-v2 label: Write the setup report model_pi: openai/gpt-5.6-luna effort_pi: low model_sdk: claude-sonnet-4-6 effort_sdk: high -skills: [posthog-integration-report, posthog-integration-notebook] +skills: [integration-v2-report, integration-v2-notebook] allowedTools: [Read, Write, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [dashboard] From 012623d0a7652086e5110f9bc013a1a1135abcbe Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 15 Jul 2026 18:46:19 -0400 Subject: [PATCH 35/38] refactor(commandments): drop per-SDK empty-key rules (now universal in wizard) Co-Authored-By: Claude Opus 4.8 --- context/commandments.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/context/commandments.yaml b/context/commandments.yaml index bf559b9b..a04e20d0 100644 --- a/context/commandments.yaml +++ b/context/commandments.yaml @@ -44,7 +44,6 @@ commandments: - When a reverse proxy is configured, both /static/* AND /array/* must route to the assets origin (us-assets.i.posthog.com or eu-assets.i.posthog.com). - posthog-js is the JavaScript SDK package name - posthog.init() MUST be called before any other PostHog methods (capture, identify, etc.) - - Pass the project API key to posthog.init() straight from its env var — do NOT default it to an empty string or placeholder when missing; a missing key must fail visibly rather than silently disabling analytics (a default host URL is fine) - posthog-js is browser-only — do NOT import it in Node.js or server-side contexts (use posthog-node instead) - Autocapture is ON by default with posthog-js (tracks clicks, form submissions, pageviews). Keep autocapture enabled unless the user explicitly asks to turn it off. - NEVER send PII in posthog.capture() event properties — no emails, full names, phone numbers, physical addresses, IP addresses, or user-generated content @@ -278,7 +277,6 @@ commandments: - Adapt dependency configuration to the appropriate build.gradle(.kts) file according to the project gradle version - Call `PostHogAndroid.setup()` only once in the Application class's `onCreate()` method, so it's initialized as early as possible and only once. - Initialize PostHog in the Application class's `onCreate()` method - - The project token is a public client-side key safe to embed in the app. Source it (BuildConfig field, Gradle/local.properties) but do NOT default it to an empty string when absent — an empty key silently disables analytics; ensure a real value always ships in the build. - Ensure every activity has a `android:label` to accurately track screen views. kmp: From 5741df31982c454996573b7be0ea00ae8fdf8430 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 15 Jul 2026 18:53:42 -0400 Subject: [PATCH 36/38] feat(integration-v2): split dashboard into dashboard+insight microskills, reshape notebook Splits the monolithic dashboard skill into a `dashboard` microskill (create the container + URL handoff) and a reusable `insight` microskill (the verified trends/funnel query shapes); the dashboard agent now pulls both. Reshapes the notebook microskill into a single clean step with one positive escaping rule. Co-Authored-By: Claude Opus 4.8 --- context/agents/integration-v2/dashboard.md | 2 +- .../integration-v2/dashboard/description.md | 64 +++---------------- .../skills/integration-v2/insight/config.yaml | 11 ++++ .../integration-v2/insight/description.md | 56 ++++++++++++++++ .../integration-v2/notebook/description.md | 16 +++-- 5 files changed, 90 insertions(+), 59 deletions(-) create mode 100644 context/skills/integration-v2/insight/config.yaml create mode 100644 context/skills/integration-v2/insight/description.md diff --git a/context/agents/integration-v2/dashboard.md b/context/agents/integration-v2/dashboard.md index a3fd6de1..42b78347 100644 --- a/context/agents/integration-v2/dashboard.md +++ b/context/agents/integration-v2/dashboard.md @@ -6,7 +6,7 @@ model_pi: openai/gpt-5.6-terra effort_pi: medium model_sdk: claude-sonnet-4-6 effort_sdk: high -skills: [integration-v2-dashboard] +skills: [integration-v2-dashboard, integration-v2-insight] allowedTools: [Read, Glob, Grep] disallowedTools: [Write, Edit, Bash, enqueue_task] dependsOn: [build] diff --git a/context/skills/integration-v2/dashboard/description.md b/context/skills/integration-v2/dashboard/description.md index a895a301..1c5d1456 100644 --- a/context/skills/integration-v2/dashboard/description.md +++ b/context/skills/integration-v2/dashboard/description.md @@ -1,68 +1,24 @@ # Create a starter dashboard -Create a live PostHog dashboard named `Analytics basics (wizard)` from the events -this integration instrumented, then populate it with up to five insights — lead -with the business-critical views: conversion funnels, activation, and churn -signals. Use the exact event names from the capture step's handoff; never invent -events that were not instrumented. Keep the `(wizard)` tag with that exact casing -so a search for `(wizard)` surfaces every wizard-created artifact. +Create a live PostHog dashboard named `Analytics basics (wizard)` to hold the +views for the events this integration instrumented. Keep the `(wizard)` tag with +that exact casing so a search for `(wizard)` surfaces every wizard-created +artifact. Everything here goes through `posthog_exec` (`call `). -## Create the dashboard, then attach insights +## Create the dashboard -Create the parent dashboard first with `dashboard-create`, capture its returned -`id`, then attach every insight to it via `dashboards: []`: +Create the parent dashboard first with `dashboard-create`, and capture its +returned `id` — the insight step attaches every insight to it via +`dashboards: []`: ```json { "name": "Analytics basics (wizard)", "description": "Key views for the events instrumented by the PostHog wizard.", "tags": ["wizard"] } ``` -For `insight-create`, use these known-good query shapes — they are verified -against the MCP schema, and the common variations around them are rejected. - -A trends insight with a breakdown (breakdowns go in `breakdownFilter.breakdowns`, -an array — there is NO top-level `breakdown` field on `TrendsQuery`): - -```json -{ - "name": "Signups by plan (wizard)", - "dashboards": [], - "query": { "kind": "InsightVizNode", "source": { - "kind": "TrendsQuery", - "series": [{ "kind": "EventsNode", "event": "user_signed_up", "math": "total" }], - "interval": "day", - "dateRange": { "date_from": "-30d" }, - "breakdownFilter": { "breakdowns": [{ "type": "event", "property": "plan" }] }, - "trendsFilter": { "display": "ActionsBar" } - }} -} -``` - -A conversion funnel (window fields are camelCase and live INSIDE `funnelsFilter`, -not at the top level of `FunnelsQuery`, and not snake_case): - -```json -{ - "name": "Signup funnel (wizard)", - "dashboards": [], - "query": { "kind": "InsightVizNode", "source": { - "kind": "FunnelsQuery", - "series": [ - { "kind": "EventsNode", "event": "page_viewed" }, - { "kind": "EventsNode", "event": "user_signed_up" } - ], - "dateRange": { "date_from": "-30d" }, - "funnelsFilter": { "funnelVizType": "steps", "funnelOrderType": "ordered", "funnelWindowInterval": 14, "funnelWindowIntervalUnit": "day" } - }} -} -``` - -Valid `trendsFilter.display` values: `ActionsLineGraph`, `ActionsBar`, -`ActionsAreaGraph`, `ActionsPie`, `ActionsStackedBar`, `BoldNumber`, -`ActionsTable`. Names like `ActionsBarChart`/`ActionsBarGraph` are rejected. If an -insight call is rejected, fix the payload against these examples rather than -retrying variations. +Then create the insights (see the insight step) and attach each one to this +dashboard's `id`. ## Hand off the dashboard diff --git a/context/skills/integration-v2/insight/config.yaml b/context/skills/integration-v2/insight/config.yaml new file mode 100644 index 00000000..c367b9e2 --- /dev/null +++ b/context/skills/integration-v2/insight/config.yaml @@ -0,0 +1,11 @@ +type: docs-only +template: description.md +description: Create PostHog insights (trends, funnels) attached to a dashboard +tags: [orchestrator, insight] +variants: + - id: all + display_name: PostHog insight step + tags: [orchestrator, insight] + docs_urls: [] +cli: + role: internal diff --git a/context/skills/integration-v2/insight/description.md b/context/skills/integration-v2/insight/description.md new file mode 100644 index 00000000..d9c6a2ee --- /dev/null +++ b/context/skills/integration-v2/insight/description.md @@ -0,0 +1,56 @@ +# Create insights + +Populate the dashboard with up to five insights from the events this integration +instrumented — lead with the business-critical views: conversion funnels, +activation, and churn signals. Use the exact event names from the capture step's +handoff; never invent events that were not instrumented. Keep each name tagged +`(wizard)` with that exact casing. + +Every call goes through `posthog_exec` (`call insight-create `). Attach each +insight to the dashboard by passing its id in `dashboards: []`. + +Use these known-good query shapes — they are verified against the MCP schema, and +the common variations around them are rejected. + +A trends insight with a breakdown (breakdowns go in `breakdownFilter.breakdowns`, +an array — there is NO top-level `breakdown` field on `TrendsQuery`): + +```json +{ + "name": "Signups by plan (wizard)", + "dashboards": [], + "query": { "kind": "InsightVizNode", "source": { + "kind": "TrendsQuery", + "series": [{ "kind": "EventsNode", "event": "user_signed_up", "math": "total" }], + "interval": "day", + "dateRange": { "date_from": "-30d" }, + "breakdownFilter": { "breakdowns": [{ "type": "event", "property": "plan" }] }, + "trendsFilter": { "display": "ActionsBar" } + }} +} +``` + +A conversion funnel (window fields are camelCase and live INSIDE `funnelsFilter`, +not at the top level of `FunnelsQuery`, and not snake_case): + +```json +{ + "name": "Signup funnel (wizard)", + "dashboards": [], + "query": { "kind": "InsightVizNode", "source": { + "kind": "FunnelsQuery", + "series": [ + { "kind": "EventsNode", "event": "page_viewed" }, + { "kind": "EventsNode", "event": "user_signed_up" } + ], + "dateRange": { "date_from": "-30d" }, + "funnelsFilter": { "funnelVizType": "steps", "funnelOrderType": "ordered", "funnelWindowInterval": 14, "funnelWindowIntervalUnit": "day" } + }} +} +``` + +Valid `trendsFilter.display` values: `ActionsLineGraph`, `ActionsBar`, +`ActionsAreaGraph`, `ActionsPie`, `ActionsStackedBar`, `BoldNumber`, +`ActionsTable`. Names like `ActionsBarChart`/`ActionsBarGraph` are rejected. If an +insight call is rejected, fix the payload against these examples rather than +retrying variations. diff --git a/context/skills/integration-v2/notebook/description.md b/context/skills/integration-v2/notebook/description.md index d289b222..bbe41b83 100644 --- a/context/skills/integration-v2/notebook/description.md +++ b/context/skills/integration-v2/notebook/description.md @@ -4,19 +4,27 @@ Once `posthog-setup-report.md` exists, mirror it into a shareable PostHog notebo so the user has an in-app copy to link and comment on. The notebook is an extra copy, not a replacement — keep the local report file in place. -Call `notebooks-create` through `posthog_exec` with a `title` (e.g. -`PostHog setup (wizard) – `) and `content` set to a single markdown -node that wraps the report verbatim: +First `Read` the finished `posthog-setup-report.md` (don't reconstruct it from +memory, and don't read it before the report step has written it). Then create the +notebook in a single `notebooks-create` call through `posthog_exec` — that exact +tool name, no tool search — with a `title` and `content` that wraps the report in +one `ph-markdown-notebook` node: ```json { "title": "PostHog setup (wizard) – ", "content": { "type": "doc", "content": [ - { "type": "ph-markdown-notebook", "attrs": { "nodeId": "markdown-notebook-v2", "markdown": "" } } + { "type": "ph-markdown-notebook", "attrs": { "nodeId": "markdown-notebook-v2", "markdown": "" } } ]} } ``` +The report goes in verbatim, but `markdown` is a JSON string field: build the +whole argument as one valid JSON value so the report's newlines and quotes are +escaped as normal JSON string encoding (`\n`, `\"`, `\\`). Never paste raw +multi-line text into the JSON, and never trim or summarize the report to make it +parse — if the call is rejected, the fix is always the escaping. + Take the `short_id` from the response, build the URL as `/project//notebooks/`, and emit it on its own line in your final message with this exact marker so the wizard surfaces it: From afa69f30554efce9bfe494a162d0ff8289b02dca Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 15 Jul 2026 18:54:23 -0400 Subject: [PATCH 37/38] fix(integration-v2): report step handles a stale report from a prior run MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Read-then-replace when posthog-setup-report.md already exists (harnesses refuse to overwrite an unread file) — the salvaged half of the closed #241. Co-Authored-By: Claude Opus 4.8 --- context/skills/integration-v2/report/description.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/context/skills/integration-v2/report/description.md b/context/skills/integration-v2/report/description.md index 197d9978..80a45c62 100644 --- a/context/skills/integration-v2/report/description.md +++ b/context/skills/integration-v2/report/description.md @@ -1,7 +1,10 @@ # Write the setup report Write `posthog-setup-report.md` at the project root summarizing the integration. -It is a new file you create — write it directly, do not read it first. +When the file doesn't exist, write it directly — don't attempt a read first. If a +previous run left one behind, `Read` it, then replace it wholesale (harnesses +refuse to overwrite a file that wasn't read; nothing in the old report is worth +merging). Draw on two sources only: - the run's queue log — `.posthog-wizard-cache/queue.json`, which holds each From 60bf5f016ded68b7e65dc8b1a361d0fc167648a5 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 15 Jul 2026 19:08:35 -0400 Subject: [PATCH 38/38] feat(integration-v2): mcp microskill for the steps that call PostHog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Surfaces the canonical shared/mcp-tool-calling grammar as an integration-v2 microskill via the {{> }} partial (shared file stays the single source), and wires it into the two agents that call the MCP — dashboard and report. Co-Authored-By: Claude Opus 4.8 --- context/agents/integration-v2/dashboard.md | 2 +- context/agents/integration-v2/report.md | 2 +- context/skills/integration-v2/mcp/config.yaml | 11 +++++++++++ context/skills/integration-v2/mcp/description.md | 7 +++++++ 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 context/skills/integration-v2/mcp/config.yaml create mode 100644 context/skills/integration-v2/mcp/description.md diff --git a/context/agents/integration-v2/dashboard.md b/context/agents/integration-v2/dashboard.md index 42b78347..e3844527 100644 --- a/context/agents/integration-v2/dashboard.md +++ b/context/agents/integration-v2/dashboard.md @@ -6,7 +6,7 @@ model_pi: openai/gpt-5.6-terra effort_pi: medium model_sdk: claude-sonnet-4-6 effort_sdk: high -skills: [integration-v2-dashboard, integration-v2-insight] +skills: [integration-v2-dashboard, integration-v2-insight, integration-v2-mcp] allowedTools: [Read, Glob, Grep] disallowedTools: [Write, Edit, Bash, enqueue_task] dependsOn: [build] diff --git a/context/agents/integration-v2/report.md b/context/agents/integration-v2/report.md index 4bd58a3a..7c80deed 100644 --- a/context/agents/integration-v2/report.md +++ b/context/agents/integration-v2/report.md @@ -6,7 +6,7 @@ model_pi: openai/gpt-5.6-luna effort_pi: low model_sdk: claude-sonnet-4-6 effort_sdk: high -skills: [integration-v2-report, integration-v2-notebook] +skills: [integration-v2-report, integration-v2-notebook, integration-v2-mcp] allowedTools: [Read, Write, Glob, Grep] disallowedTools: [enqueue_task] dependsOn: [dashboard] diff --git a/context/skills/integration-v2/mcp/config.yaml b/context/skills/integration-v2/mcp/config.yaml new file mode 100644 index 00000000..2419adb1 --- /dev/null +++ b/context/skills/integration-v2/mcp/config.yaml @@ -0,0 +1,11 @@ +type: docs-only +template: description.md +description: How to call PostHog MCP tools (discover, inspect, then call) +tags: [orchestrator, mcp] +variants: + - id: all + display_name: PostHog MCP step + tags: [orchestrator, mcp] + docs_urls: [] +cli: + role: internal diff --git a/context/skills/integration-v2/mcp/description.md b/context/skills/integration-v2/mcp/description.md new file mode 100644 index 00000000..5c472fb0 --- /dev/null +++ b/context/skills/integration-v2/mcp/description.md @@ -0,0 +1,7 @@ +# Call PostHog MCP tools + +Any step that creates something in PostHog — a dashboard, an insight, a notebook — +does it through the PostHog MCP. Discover and inspect before you call; never guess +a tool name or the shape of its input. + +{{> mcp-tool-calling}}