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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions context/agents/error-tracking/capture-exceptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
type: capture-exceptions
flow: error-tracking
label: Wire up exception capture
model_pi: openai/gpt-5.6-sol
effort_pi: medium
model_sdk: claude-sonnet-4-6
effort_sdk: high
skills: [integration-v2-error-tracking-step, posthog-best-practices]
allowedTools: [Read, Write, Edit, Glob, Grep]
disallowedTools: [enqueue_task]
dependsOn: [install, init]
---

## Goal

Make the errors the app does not catch reach PostHog, by whatever means the
SDK offers for that. Which means depends on the SDK: some autocapture
exceptions once you enable it at init, some wire into the framework's own
error handler, some give you a boundary to mount at the app entry. Follow the
docs and the reference example for this one, and set it up in one place —
never manual capture calls sprinkled across files.

The SDK is installed and initialized — either it already was, or the install
and init tasks before you did it (see their handoffs); 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 — the user-driven test-setup step at the end of
the flow verifies, when the user wants it. Do not touch the build config
either way; when the flow includes a configure task, it owns those files.
Stay inside this project's directory and set up that one place; that is the
whole job.

## How you know you succeeded

An error the app does not catch reaches PostHog, through the mechanism this
SDK gives you rather than one you invented. You did not install anything, run
a build, lint, or tests, search outside the project, or read through the whole
app or hand-wrap individual components or routes. Your handoff names the files
you changed and the capture mechanism, so the report can explain it to the
user.
47 changes: 47 additions & 0 deletions context/agents/error-tracking/configure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
type: configure
flow: error-tracking
label: Apply build-config changes
model_pi: openai/gpt-5.6-sol
effort_pi: medium
model_sdk: claude-sonnet-4-6
effort_sdk: medium
skills: []
allowedTools: [Read, Write, Edit, Glob, Grep, Bash, load_skill_menu, install_skill]
disallowedTools: [enqueue_task]
dependsOn: [capture-exceptions]
---

## Goal

Make this project's production build emit and upload source maps (or, for Go
and Rust, native debug symbols). Install the skill your task input names
(`install_skill` with the `skillId`) and read it — it is the source of truth
for the per-framework build-config and the uploader wiring.

Two of the skill's steps are yours:

- **"Apply build-config changes"** — make the bundler / build-config edits the
skill instructs for this platform, so the build produces and injects the
chunk IDs PostHog needs and runs the uploader.
- **"Make credentials available at build time"** — do the skill's step so the
build can read the upload credentials from the environment. If it calls for a
loader (e.g. `dotenv`), install it SILENTLY with the project's package
manager. Skip this step entirely when the platform already auto-loads `.env`.

Install every dependency with the project's own package manager: call
`detect_package_manager` before the first install and use its answer,
translating any `npm install` the skill or docs show (`pnpm add -D …`,
`yarn add -D …`). In a pnpm or yarn workspace, npm fails outright on
`workspace:*` dependencies (`EUNSUPPORTEDPROTOCOL`) — that error means the
wrong manager, never a flag to retry with.

Do not write any credential values and do not create env files — the
`credentials` task owns that, in parallel with you. Do not run the build.

## How you know you succeeded

The build config carries the skill's source-map / debug-symbol changes and can
read its credentials from the environment at build time. Your handoff names
every file you changed and the exact build-config keys you added, so the CI
task can wire the same variables through the pipeline.
50 changes: 50 additions & 0 deletions context/agents/error-tracking/credentials.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
type: credentials
flow: error-tracking
label: Get and write the upload credentials
model_pi: openai/gpt-5.6-sol
effort_pi: medium
model_sdk: claude-sonnet-4-6
effort_sdk: medium
skills: []
allowedTools: [Read, Write, Edit, Glob, Grep, Bash, load_skill_menu, install_skill, wizard_ask]
disallowedTools: [enqueue_task]
dependsOn: []
---

## Goal

Put the PostHog source-map upload credentials into this project's environment.
Install the skill your task input names (`install_skill` with the `skillId`)
and follow its **"Write credentials to the env file"** step for the variable
names and the env file to pick.

The upload needs a PostHog **personal API key** at build time. Only the user can
mint one — never call the PostHog API or any tool to create it. Get it and
write it in this one task (the key never survives across tasks):

1. Ask with `wizard_ask`, exactly:
`{ id: "api-key", prompt: "Paste your PostHog personal API key below.\n\nDon't have one yet? Create one here:\n<SETTINGS_URL>\n\nWhen creating the key, choose the 'Source map upload' preset, then come back and paste it here.", kind: "text", sensitive: true }`
You receive `{ secretRef: "secret:..." }` — a vaulted reference, never the raw
value. If `wizard_ask` is unavailable (non-interactive run), report this task
with status `not needed` and say in your handoff that the user must create
the key and set the variables themselves; do not block.
2. Pick the env file per the skill (reuse the one PostHog's SDK already writes
its `POSTHOG_*` vars to, when there is one). Call `check_env_keys` on it
first (it returns present/absent, never values — never read the file
directly).
3. Call `set_env_values`, passing the secretRef as a value object, not a
literal string — e.g.
`values: { "POSTHOG_CLI_API_KEY": { secretRef: "<the ref>" }, "POSTHOG_CLI_PROJECT_ID": "<PROJECT_ID>", "POSTHOG_CLI_HOST": "<UI_HOST>" }`.
The exact variable names follow the skill's per-uploader convention. The
wizard resolves the ref locally, so you never see the key value.

Replace `<SETTINGS_URL>`, `<PROJECT_ID>`, and `<UI_HOST>` from your project
context. Do not touch the build config — the `configure` task owns that.

## How you know you succeeded

The env file holds the upload variables (the key as a resolved secret, the
non-secret project id and host as literals), written through the wizard tools,
never hardcoded in source. Your handoff names the env file and every variable
name — never a value — so the CI task carries the same names into the pipeline.
33 changes: 33 additions & 0 deletions context/agents/error-tracking/init.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
type: init
flow: error-tracking
label: Set up PostHog initialization
model_pi: openai/gpt-5.6-sol
effort_pi: low
model_sdk: claude-sonnet-4-6
effort_sdk: medium
skills: [integration-v2-init, posthog-best-practices]
allowedTools: [Read, Write, Edit, Glob, Grep]
disallowedTools: [enqueue_task]
dependsOn: []
---

## Goal

Make sure PostHog is initialized. If the project already has a working
`posthog.init(...)` (or the framework's equivalent) with its env keys wired,
leave it alone and say so in your handoff. If it doesn't, create it following
your skill — it owns the how: the framework's init point, the env-var wiring
through the wizard tools, and `.env.example`.

You only exist in this flow because the user asked for error tracking on a
repo without PostHog. Initialize the SDK so exceptions can flow and stop —
no instrumentation, no extras. Don't set up exception capture either way;
the capture-exceptions task after you owns that.

## How you know you succeeded

An init point exists with the PostHog env keys present — whether it already
did or you just created it — keys in the env file, never hardcoded. Your
handoff names the files involved and how the client is constructed, so the
capture-exceptions task can find the init options without re-discovering them.
31 changes: 31 additions & 0 deletions context/agents/error-tracking/install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
type: install
flow: error-tracking
label: Add the PostHog SDK to the manifest
model_pi: openai/gpt-5.6-sol
effort_pi: low
model_sdk: claude-haiku-4-5-20251001
skills: [integration-v2-install]
allowedTools: [Read, Edit, Glob, Grep, Bash]
disallowedTools: [enqueue_task]
dependsOn: []
---

## Goal

Make sure the PostHog SDK is in the manifest. If it's already installed,
leave it alone and say so in your handoff. If it isn't, install it following
your skill — it owns the how: the package manager rules, the version rules,
what counts as an environment failure, and the fallback.

You only exist in this flow because the user asked for error tracking on a
repo without PostHog. Install the SDK the errors will report through (the
server library too, if the app runs server-side code) and stop — no
instrumentation, no extras.

## How you know you succeeded

The SDK is declared in the manifest at a real version — whether it already
was or you just installed it — or your handoff plainly says why the
environment stopped you. Your handoff names the manifest and the package, so
later steps import it under the name they will actually get.
64 changes: 64 additions & 0 deletions context/agents/error-tracking/report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
type: report
flow: error-tracking
label: Summarise and hand off
sink: true
model_pi: openai/gpt-5.6-luna
effort_pi: low
model_sdk: claude-sonnet-4-6
effort_sdk: medium
skills: []
allowedTools: [Read, Glob, Grep, Write, posthog_exec]
disallowedTools: [enqueue_task]
dependsOn: [capture-exceptions, wire-ci, test-setup]
---

## Goal

Tell the user what error tracking now does for them and what they still have
to do, from the handoffs of every task in the run. `read_handoffs` gives you
each task's report — the capture mechanism, the files changed, the env
variable names, the CI secret to create, and any deploy path that could not be
traced. Do not re-derive any of it from the project.

First, turn on the Error Tracking product for the team (`products-enable`
through `posthog_exec`) so the captured exceptions have a UI to land in. If
the call fails or the tool is missing, carry it as a follow-up — never fail
the report over it.

Write the hand-off to `posthog-error-tracking-report.md` at the top level of
this project's directory. When the run wired source-map upload, START it with
a **"What you still need to do"** section — numbered, copy-pasteable:

1. Create a personal API key with the 'Source map upload' preset at
`<UI_HOST>/settings/user-api-keys` (skip when the credentials handoff says
the key is already written).
2. Add it as the CI secret the wire-ci step referenced, named exactly as in
the pipeline config.
3. Any other manual follow-up the handoffs carry (an untraceable deploy path,
provider-side settings).

Then cover, briefly and concretely:

- How uncaught errors reach PostHog now — the capture mechanism and the files
that carry it.
- If the run also installed and initialized the SDK, say so — the user
started this command without PostHog and now has it.
- When source-map upload was wired: the files changed (paths only), the exact
production build command, and that every production build now uploads.
- When it was skipped: one line saying why (readable stack traces on this
platform) — an outcome, not an apology.
- How to verify: trigger any error and look at
`<UI_HOST>/project/<PROJECT_ID>/error_tracking`; uploaded symbol sets appear
at `<UI_HOST>/project/<PROJECT_ID>/error_tracking/configuration`.

Never write a secret value into the report — only variable names. Replace
`<UI_HOST>` and `<PROJECT_ID>` from your project context. Give the same
summary in chat.

## How you know you succeeded

`posthog-error-tracking-report.md` exists and a user who reads only it knows
how errors reach PostHog, the follow-ups they still owe (the API key and the
CI secret named exactly, when upload was wired), and where in PostHog to see
the first captured exception.
90 changes: 90 additions & 0 deletions context/agents/error-tracking/setup-error-tracking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
type: setup-error-tracking
flow: error-tracking
seed: true
model_pi: openai/gpt-5.6-terra
effort_pi: medium
model_sdk: claude-sonnet-4-6
effort_sdk: high
skills: []
allowedTools: [Read, Glob, Grep, posthog_exec]
disallowedTools: [Write, Edit, Bash, complete_task]
dependsOn: []
---

## Goal

Plan a PostHog Error Tracking setup and seed the task queue. The end state:
errors the app does not catch reach PostHog, and — where the platform ships
minified bundles or stripped binaries — production builds upload the source
maps or debug symbols that make the stack traces readable.

First establish two facts from the repo:

**1. Is PostHog already integrated?** Look for `posthog-js` or a server SDK in
the dependency manifests, or a `posthog.init(...)` / snippet in the source.
Check the project state for existing events if the repo is ambiguous.

**2. Which uploader variant is this project — or none?** Read the manifests
and pick at most one, by this precedence (first match wins):

- `pubspec.yaml` → `flutter`
- an `.xcodeproj`, `Podfile`, or `Package.swift` → `ios`
- a Gradle build file (`build.gradle`, `build.gradle.kts`, `settings.gradle`) → `android`
- `go.mod` → `go`
- `Cargo.toml` → `rust`
- otherwise read `package.json` dependencies, first match wins:
`react-native` → `react-native`; `nuxt` → `nuxt`; `next` → `nextjs`;
`@angular/core` → `angular`; `vite` → `vite`; `webpack` → `webpack`;
`rollup` → `rollup`; `react` → `react`; server-only Node → `node`;
any other browser JS → `web`
- **none** for platforms whose stack traces are already readable: plain
Python (Django, Flask, FastAPI), Ruby, PHP, Elixir, JVM servers, .NET.
Skip the whole upload subgraph for them — a skipped upload on such a
platform is an outcome, not a gap.

When a variant matched, the uploader skill id is
`error-tracking-upload-source-maps-<variant>`. Pass it to the four upload
tasks as `inputs: { skillId: "<id>", displayName: "<human platform name>" }`
so no task re-detects.

The two facts are independent — settle BOTH before you enqueue anything.
"PostHog is already integrated" answers fact 1 only; it never decides fact 2,
and an already-integrated project still gets the upload subgraph when a
variant matches. A compiled or bundled JS project always has one: a Node
service built with `tsc` ships minified/compiled output, so it is the `node`
variant, not "none". Only the readable-stack platforms listed above skip the
subgraph.

Then seed the graph:

- `install` and `init`, independent of each other — **only when PostHog is
not integrated**. Do not stop on an uninstrumented repo, integrate.
- `capture-exceptions`, after `install` and `init` (with no dependencies when
PostHog was already integrated).
- When an uploader variant matched, add the upload subgraph:
- `credentials`, no dependencies — it stops to ask the user for a personal
API key, so keep it a root task: the prompt reaches the user early while
the code tasks run.
- `configure`, after `capture-exceptions` — build-config changes; it runs
after the code edits so the two never fight over the same files.
- `wire-ci`, after `configure` and `credentials`.
- `test-setup`, after `wire-ci` — offers the user a local end-to-end test
last, once everything is wired.
- `report`, after every other queued task. It writes the handoff last, so it
describes what actually shipped.

Never plan an identify, capture, dashboard, or session-replay task — this run
sets up error tracking, not the full integration. The minimal SDK footprint
that `install` and `init` leave behind is enough for exceptions to flow.

## How you know you succeeded

Every task in the chosen graph is queued with that dependency shape, the four
upload tasks (when queued) share the same `{ skillId, displayName }` inputs,
`report` depends on the rest (directly or transitively), and the first task is
runnable. Your plan states both facts explicitly: whether PostHog was
integrated, and which uploader variant matched — or, when you queue no upload
tasks, which readable-stack platform this is and why no variant applies. A
plan that never mentions fact 2 is an incomplete plan, not a decision. Keep
labels short — the action in a few words.
Loading
Loading