Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
54a4353
test: lock iOS source-map skill contract
ablaszkiewicz Jul 11, 2026
f5e0a83
feat: document iOS xcconfig credential flow for source-map upload
ablaszkiewicz Jul 14, 2026
88a8b12
feat: pin the verified iOS dSYM upload pipeline in the source-maps skill
ablaszkiewicz Jul 15, 2026
2e42624
feat: pin xcconfig chaining direction and credential-fallback traps f…
ablaszkiewicz Jul 15, 2026
f309fb2
refactor: slim the iOS source-maps guidance to a minimal shell
ablaszkiewicz Jul 15, 2026
5296059
fix: iOS local test is one Xcode step, not a CLI/GUI mix
ablaszkiewicz Jul 15, 2026
a012d1d
fix: tie POSTHOG_INCLUDE_SOURCE=1 to its failure symptom
ablaszkiewicz Jul 15, 2026
2ba7c3d
refactor: trim include-source note to one clause
ablaszkiewicz Jul 15, 2026
19a959a
refactor: mandate the include-source prefix on the snippet itself
ablaszkiewicz Jul 15, 2026
a4736d2
refactor: minimal iOS shell — all creds in one xcconfig, no fallbacks
ablaszkiewicz Jul 15, 2026
d0c790a
fix: include-source flag lives in the xcconfig; fileRef in the root g…
ablaszkiewicz Jul 15, 2026
3eb8fc3
revert: include-source stays an inline prefix on the invocation
ablaszkiewicz Jul 15, 2026
1d03ec5
feat(ios): credentials move from xcconfig to gitignored .env
ablaszkiewicz Jul 15, 2026
6ae2731
fix(ios): dotenv path rides POSTHOG_CLI_DOTENV_FILE, read by the CLI …
ablaszkiewicz Jul 15, 2026
e6ca679
chore(ios): drop redundant trailer after the test-snippet
ablaszkiewicz Jul 15, 2026
994d1da
fix: move stuff to context mill
ablaszkiewicz Jul 16, 2026
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
24 changes: 21 additions & 3 deletions context/skills/error-tracking-upload-source-maps/description.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ Wire source map generation, chunk-ID injection, and upload into your **productio
#### Examples
- **Node / tsc** Emit maps with embedded sources by setting both in `tsconfig.json`: `"sourceMap": true` and `"inlineSources": true`. Then run `posthog-cli sourcemap process` against the build output dir as a post-build step — it injects chunk IDs and uploads in one pass, and needs the upload credentials (see "Make credentials available at build time").
- **Vite / Webpack / Rollup** Prefer the bundler plugin from the reference over hand-rolling the CLI — it injects and uploads in one pass. Make sure the bundler is configured to emit source maps.
- **iOS (Xcode)** iOS uploads **dSYM debug symbols**, not source maps. Required target changes:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be time to use variants, I think this will turn to noise and poison your prompts as this list grows.

You can also do this later, it's a larger change.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you pulling in docs at all, you should:

  • have all these tidbits in docs
  • Create variants for each docs page (for each platfomr/framework)
  • Profit?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am using docs and this is all in the docs but I had to add this here explicitly or agent was just lost sometimes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops one thing is not mentioned in the docs. New env variable for dotenv file for the CLI. But agent got lost at cocoa vs SPM and how to properly set the command.

I had to do TONS of back and forth with experimenting with what to put in the context for the agent to finally understand that

1. `DEBUG_INFORMATION_FORMAT = dwarf-with-dsym` for Release.
2. `ENABLE_USER_SCRIPT_SANDBOXING = NO`.
3. A Run Script phase, ordered last, with `$(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)/Contents/Resources/DWARF/$(EXECUTABLE_NAME)` in its Input Files, calling the SDK's bundled script — do not hand-roll the upload:
- SPM: `POSTHOG_INCLUDE_SOURCE=1 POSTHOG_CLI_DOTENV_FILE="${SRCROOT}/.env" "${BUILD_DIR%/Build/*}/SourcePackages/checkouts/posthog-ios/build-tools/upload-symbols.sh"`
- CocoaPods: `POSTHOG_INCLUDE_SOURCE=1 POSTHOG_CLI_DOTENV_FILE="${SRCROOT}/.env" "${PODS_ROOT}/PostHog/build-tools/upload-symbols.sh"`
Copy the invocation verbatim — the `POSTHOG_INCLUDE_SOURCE=1` and `POSTHOG_CLI_DOTENV_FILE` prefixes HAVE to be there. This needs a recent `posthog-cli` (older ones silently ignore `POSTHOG_CLI_DOTENV_FILE`); the PostHog wizard installs it for you, so do not run `npm install -g` yourself.
- **Next.js / Nuxt / Angular** Use the framework's documented source-map upload integration from the reference; these own their build pipeline, so configure upload there rather than bolting on a separate CLI step.
- **React Native / Android / iOS / Flutter** You upload platform debug symbols (Hermes maps, ProGuard/R8 mappings, dSYMs) rather than plain `.js.map` files — follow the platform reference for the exact build hook.

Expand All @@ -50,6 +57,7 @@ The upload credentials must be readable **by the build pipeline at build time**,
- **Does NOT auto-load `.env`**: Rollup, plain webpack, and plain Node scripts. Load it explicitly — add `dotenv` (`require('dotenv').config()`, or `import 'dotenv/config'` for ESM) at the top of the bundler/config file.
- **Separate-process gotcha**: if `posthog-cli sourcemap process` runs as its own `package.json` step (after the bundler), the CLI call is a **separate child process** and will *not* see env vars a loader set inside the bundler config. Point the CLI at the file directly: `posthog-cli --dotenv-file <relative-path> sourcemap process …` (the flag goes before the subcommand).
- **`process` authenticates from the start.** `posthog-cli sourcemap process` resolves credentials before it injects chunk IDs — the inject phase needs them too, not just the upload — and fails without them. Always pass `--dotenv-file` to the `process` invocation. (It can still appear to work if the developer once ran `posthog-cli login`, which leaves credentials in `~/.posthog` — that won't exist in CI or on a teammate's machine.)
- **iOS / Xcode** No loader — the Run Script phase's `POSTHOG_CLI_DOTENV_FILE="${SRCROOT}/.env"` prefix points posthog-cli at the gitignored `.env`. `POSTHOG_CLI_HOST` is the API host (`https://us.posthog.com`), never the `*.i.posthog.com` ingestion host.

#### Examples
- **Next.js / Nuxt** Auto-load `.env` at build time; put the vars there and you're done.
Expand All @@ -70,6 +78,7 @@ The upload credentials must be readable **by the build pipeline at build time**,
```json
"build": "tsc && posthog-cli --dotenv-file .env sourcemap process --directory ./dist --release-name my-app"
```
- **iOS (Xcode / posthog-cli)** A gitignored `.env` next to the `.xcodeproj` — the Run Script invocation's `POSTHOG_CLI_DOTENV_FILE="${SRCROOT}/.env"` prefix hands it to posthog-cli. No Xcode project wiring beyond the Run Script phase. In CI, set the `POSTHOG_CLI_*` values as job secrets instead — no `.env` on the runner.

### Write credentials to the env file

Expand All @@ -96,7 +105,7 @@ Resolve two concrete commands for this project: the production **build** command
- **Vite** Build: `npm run build`. Run: `npm run preview`.
- **Plain Node** Build: `npm run build`. Run: `node <built entry>` — read package.json `main`/`bin` and the build output dir to name the real file (e.g. `node dist/index.js`).
- **Android** Build: `./gradlew assembleRelease`. Run: launch on a device/emulator (Android Studio, or `./gradlew installRelease`).
- **iOS** Build: `xcodebuild …`. Run: launch the scheme on a simulator/device (Xcode).
- **iOS** Local build + run are one step: Xcode Run with Build Configuration = Release. `xcodebuild` is CI-only.
- **Flutter** Build: `flutter build apk` / `flutter build ios`. Run: `flutter run`.
- **React Native** Run: `npx react-native run-ios` / `npx react-native run-android`.

Expand Down Expand Up @@ -267,15 +276,24 @@ Optionally add a temporary, clearly-labeled affordance that captures one test ex
- The handler must call the SDK's exception-capture method **directly** — do **not** `throw`. Throwing depends on the global error handler and shows a dev overlay; a direct capture is deterministic across platforms.
- Pass a single Error (or platform-equivalent throwable). No custom message beyond the Error, no extra properties, no second argument — the Error's stack trace is what gets resolved.
- Use distinctive copy on the trigger (button label / route path) so the resulting event is easy to find in the UI.
- Read any file before editing it and capture its exact contents; after testing, restore every touched file and re-read to confirm nothing is left behind. Never leave the affordance in place — even if the test "didn't work", revert first.
- Read any file before editing it and capture its exact contents; after testing, restore every file the affordance touched — the affordance only, leave the upload and credential wiring in place — and re-read to confirm nothing is left behind. Never leave the affordance in place — even if the test "didn't work", revert first.
- The upload only happens on the *production build*: build, run, trigger the error, then confirm the stack trace in Error Tracking points at real source files, not minified bundle paths.

#### Examples
- **Browser / SPA / SSR (web, react, nextjs, nuxt, angular, vite, webpack, rollup)** Add a button such as "Test PostHog Error Tracking" on the home/root page whose onClick calls `posthog.captureException(new Error("PostHog source maps test"))`.
- **Node.js** Add a temporary route (e.g. `GET /__posthog-test-error`) on the existing server that calls `posthog.captureException(new Error("PostHog source maps test"))` and returns 200. With no HTTP layer, add the capture to the existing entry script where the client is initialised rather than creating a new file. Tell the user the exact command/URL to hit.
- **React Native** Add a visible `Button` on the main screen whose onPress calls `posthog.captureException(new Error("PostHog source maps test"))`.
- **Android (Kotlin)** Add a `Button` on the launcher Activity whose onClick captures a `Throwable` via the PostHog SDK, per the reference.
- **iOS (Swift)** Add a `UIButton` on the root view controller whose action captures an `NSError` via the PostHog SDK, per the reference.
- **iOS (Swift)** `Button` on the root view (SwiftUI) or `UIButton` on the root view controller (UIKit), handler:
```swift
do {
throw NSError(domain: "PostHogSourceMapTest", code: 1,
userInfo: [NSLocalizedDescriptionKey: "Source map upload test error"])
} catch {
PostHogSDK.shared.captureException(error)
}
```
(`capture()` takes an event-name String, not an Error.) Test flow — give the user these steps verbatim, everything happens in Xcode (no `xcodebuild`): 1) In Xcode: Edit Scheme ▸ Run ▸ Build Configuration ▸ Release, then Run — the Release build uploads dSYMs automatically. 2) Tap the "<your test button label>" button in the app. It's an event, not a crash — no debugger-detach or relaunch steps.
- **Flutter** Add an `ElevatedButton` on the home widget whose onPressed calls `Posthog().captureException(Exception("PostHog source maps test"))`.

### Verify and hand off
Expand Down
30 changes: 30 additions & 0 deletions scripts/lib/tests/error-tracking-upload-source-maps.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { describe, expect, it } from 'vitest';
import { join } from 'path';

import { expandSkillGroups, loadSkillsConfig } from '../skill-generator.js';

const CONFIG_DIR = join(process.cwd(), 'context');

describe('error-tracking-upload-source-maps iOS variant', () => {
it('expands to the skill contract consumed by the wizard', () => {
const config = loadSkillsConfig(CONFIG_DIR);
const skills = expandSkillGroups(config, CONFIG_DIR);
const ios = skills.find((skill) => skill.id === 'error-tracking-upload-source-maps-ios');

expect(ios).toMatchObject({
id: 'error-tracking-upload-source-maps-ios',
_shortId: 'ios',
_category: 'error-tracking-upload-source-maps',
_group: 'error-tracking-upload-source-maps',
display_name: 'iOS',
description: 'Upload dSYM debug symbols to PostHog Error Tracking for iOS',
tags: ['error-tracking', 'source-maps', 'ios', 'swift'],
docs_urls: ['https://posthog.com/docs/error-tracking/upload-source-maps/ios.md'],
_sharedDocs: [
'https://posthog.com/docs/error-tracking/upload-source-maps.md',
'https://posthog.com/docs/error-tracking/upload-source-maps/cli.md',
],
_cli: null,
});
});
});
Loading