From 83148a53a650871ecd7ac2a5990ef36c39b16eb7 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Thu, 8 Oct 2026 17:58:35 +0500 Subject: [PATCH 1/4] feat(ai): generate the SDK agent skills from bugsee-for-ai MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The skills served at docs.bugsee.com/ai/agent-skills/sdk/** were hand-kept forks of bugsee/bugsee-for-ai and had drifted (Android 7.0.0-beta3 vs 7.3.0, Flutter ^8.0.0 vs 9.0.4, KMP 0.1.1 vs 0.1.2, old CLI guidance). Make bugsee-for-ai the only place a skill is edited: - scripts/mirror-skills.mjs generates the docs copies from a pinned bugsee-for-ai commit (frontmatter rewritten for Docusaurus, plugin breadcrumbs removed, sibling links made absolute, unknown links fail). --check fails on hand edits; --update moves the pin to main. - .github/workflows/sync-agent-skills.yml opens one rolling PR with the regenerated copies when bugsee-for-ai changes (repository_dispatch, plus a 6-hourly poll as a fallback). It runs spell check and the build itself and opens a draft PR if either fails. - deploy.yml runs the unit tests and --check on every PR. - Existing curl URLs are unchanged. sdk/ios/v7 has no plugin source yet and stays docs-owned (listed in skills-map.json). - Index table: Android is now 6.x / 7.x (7.3.0 is released, not a beta). - cspell: add unbreak, Podspec. πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Ibfb9ed25686dcce24fc1396ea070ccf77049a756 --- .claude/CLAUDE.md | 1 + .github/workflows/deploy.yml | 7 + .github/workflows/sync-agent-skills.yml | 119 +++++++++ cspell.json | 4 +- docs/ai/agent-skills/index.md | 4 +- docs/ai/agent-skills/sdk/android/SKILL.md | 86 +++++-- docs/ai/agent-skills/sdk/android/v7/SKILL.md | 231 ++++++++++++++---- docs/ai/agent-skills/sdk/cordova/SKILL.md | 30 ++- docs/ai/agent-skills/sdk/dotnet/SKILL.md | 23 +- docs/ai/agent-skills/sdk/flutter/SKILL.md | 25 +- docs/ai/agent-skills/sdk/ios/SKILL.md | 169 ++++++++++--- docs/ai/agent-skills/sdk/kmp/SKILL.md | 120 ++------- .../ai/agent-skills/sdk/react-native/SKILL.md | 46 +++- docs/ai/agent-skills/sdk/unity/SKILL.md | 26 +- docs/ai/agent-skills/sdk/xamarin/SKILL.md | 29 ++- package.json | 3 + scripts/mirror-skills.mjs | 198 +++++++++++++++ scripts/mirror-skills.test.mjs | 76 ++++++ scripts/skills-map.json | 22 ++ scripts/skills-source.json | 3 + 20 files changed, 981 insertions(+), 241 deletions(-) create mode 100644 .github/workflows/sync-agent-skills.yml create mode 100644 scripts/mirror-skills.mjs create mode 100644 scripts/mirror-skills.test.mjs create mode 100644 scripts/skills-map.json create mode 100644 scripts/skills-source.json diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 15a1a14..c59568c 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -58,6 +58,7 @@ All markdown content, organized by section: ### Build Pipeline (`scripts/`) - **build.sh** β€” Runs spell check β†’ `npm run build` β†’ `node scripts/copy-raw-markdown.mjs` - **deploy.sh** β€” Manual fallback deploy: S3 sync + CloudFront invalidation (requires `S3CMD_CONFIG`, `DEPLOY_ENDPOINT`, `CLOUDFRONT_ID` env vars). CI normally deploys automatically on every push to `main` β€” see **Deployment & Git remote**. +- **mirror-skills.mjs** β€” Generates `docs/ai/agent-skills/sdk/**/SKILL.md` from `bugsee/bugsee-for-ai` (the single source of truth for agent skills). **Never edit those files here** β€” change the skill in `bugsee-for-ai`; `.github/workflows/sync-agent-skills.yml` opens a PR with the regenerated copies. Inputs: `skills-map.json` (which plugin skill feeds which docs path; `docsOwned` lists files that are not generated, currently `sdk/ios/v7`) and `skills-source.json` (the pinned `bugsee-for-ai` commit). `npm run mirror-skills` regenerates at the pin, `node scripts/mirror-skills.mjs --update` moves the pin to `main`, `npm run check-skills` fails on hand edits, `npm run test:mirror` runs the unit tests. - **copy-raw-markdown.mjs** β€” Post-build: copies docs to `build/` as raw `.md` files for AI agents. Strips JSX from `.mdx` files (`` β†’ bold labels), simplifies front matter to title/description/url only - **migrate-content.mjs** β€” One-time MkDocs β†’ Docusaurus migration script (already run, kept for reference) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 7aa0a5f..510857b 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -49,6 +49,13 @@ jobs: - name: Install dependencies run: npm ci + # The agent skills under docs/ai/agent-skills/sdk are generated from bugsee/bugsee-for-ai + # (see scripts/mirror-skills.mjs). Fail on hand edits to them. + - name: Agent skills mirror (tests + no hand edits) + run: | + npm run test:mirror + npm run check-skills + - name: Spell check run: npx cspell "docs/**/*.md" "docs/**/*.mdx" --no-cache -c cspell.json diff --git a/.github/workflows/sync-agent-skills.yml b/.github/workflows/sync-agent-skills.yml new file mode 100644 index 0000000..4e50979 --- /dev/null +++ b/.github/workflows/sync-agent-skills.yml @@ -0,0 +1,119 @@ +name: Sync agent skills + +# Keeps docs/ai/agent-skills/sdk/** in step with bugsee/bugsee-for-ai, the single source of +# truth for agent skills. Whenever bugsee-for-ai main has new skill content this opens (or +# updates) ONE rolling pull request with the regenerated copies. +# +# Triggers +# * repository_dispatch "bugsee-for-ai-updated" β€” sent by bugsee-for-ai on every push to main +# that touches skills/ (needs the DOCS_SYNC_TOKEN secret there; without it that repo just +# skips the notification). +# * schedule β€” polling fallback, so a sync happens even if the notification is not set up. +# * workflow_dispatch β€” run it by hand from the Actions tab. +# +# One-time setup (see the PR that introduced this file): +# * Settings > Actions > General > "Allow GitHub Actions to create and approve pull requests". +# * Optional but recommended: a SKILLS_SYNC_TOKEN secret (fine-grained PAT or GitHub App token +# with Contents + Pull requests write on this repo). PRs opened with the default GITHUB_TOKEN do +# not trigger the "Build and Deploy" checks; this job therefore runs the spell check and the +# site build itself and opens the PR as a DRAFT if either fails. + +on: + repository_dispatch: + types: [bugsee-for-ai-updated] + schedule: + - cron: '23 */6 * * *' + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +concurrency: + group: sync-agent-skills + cancel-in-progress: false + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Setup Node.js + uses: actions/setup-node@v7 + with: + node-version: 20 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Regenerate from bugsee-for-ai main + id: mirror + run: | + old="$(node -p "require('./scripts/skills-source.json').ref")" + node scripts/mirror-skills.mjs --update + new="$(node -p "require('./scripts/skills-source.json').ref")" + echo "old=$old" >> "$GITHUB_OUTPUT" + echo "new=$new" >> "$GITHUB_OUTPUT" + if [ -z "$(git status --porcelain -- docs scripts/skills-source.json)" ]; then + echo "changed=false" >> "$GITHUB_OUTPUT" + echo "Nothing to sync." + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Spell check + id: spell + if: steps.mirror.outputs.changed == 'true' + continue-on-error: true + run: | + set -o pipefail + npx cspell "docs/**/*.md" "docs/**/*.mdx" --no-cache -c cspell.json 2>&1 | tee spell.log + + - name: Build site + id: build + if: steps.mirror.outputs.changed == 'true' + continue-on-error: true + run: | + set -o pipefail + npm run build 2>&1 | tee build.log + + - name: Compose PR body + if: steps.mirror.outputs.changed == 'true' + run: | + { + echo "Regenerates the SDK agent skills from [bugsee-for-ai](https://github.com/bugsee/bugsee-for-ai)." + echo + echo "Changes upstream: https://github.com/bugsee/bugsee-for-ai/compare/${{ steps.mirror.outputs.old }}...${{ steps.mirror.outputs.new }}" + echo + echo "- Spell check: **${{ steps.spell.outcome }}**" + echo "- Site build: **${{ steps.build.outcome }}**" + if [ "${{ steps.spell.outcome }}" = "failure" ]; then + echo + echo "Spell check failed. Valid terms belong in \`cspell.json\`; push that to this branch." + echo '```' + grep -E 'Unknown word' spell.log | sort -u | head -30 + echo '```' + fi + echo + echo "Generated files must not be edited here β€” fix the skill in bugsee-for-ai instead." + echo + echo "πŸ€– Generated with [Claude Code](https://claude.com/claude-code)" + } > pr-body.md + + - name: Open or update the sync PR + if: steps.mirror.outputs.changed == 'true' + uses: peter-evans/create-pull-request@v8.1.1 + with: + token: ${{ secrets.SKILLS_SYNC_TOKEN || secrets.GITHUB_TOKEN }} + branch: automation/sync-agent-skills + delete-branch: true + add-paths: | + docs/ai/agent-skills + scripts/skills-source.json + commit-message: "chore(skills): sync agent skills from bugsee-for-ai@${{ steps.mirror.outputs.new }}" + title: "chore(skills): sync agent skills from bugsee-for-ai" + body-path: pr-body.md + draft: ${{ steps.spell.outcome == 'failure' || steps.build.outcome == 'failure' }} diff --git a/cspell.json b/cspell.json index 0608bb0..d49cbf2 100644 --- a/cspell.json +++ b/cspell.json @@ -228,6 +228,8 @@ "jsbundle", "rustflags", "sandboxing", - "libil" + "libil", + "unbreak", + "Podspec" ] } \ No newline at end of file diff --git a/docs/ai/agent-skills/index.md b/docs/ai/agent-skills/index.md index 67cbb0b..1b1eb85 100644 --- a/docs/ai/agent-skills/index.md +++ b/docs/ai/agent-skills/index.md @@ -21,8 +21,8 @@ The skill files are structured markdown documents that guide AI agents through p | Platform | Prompt | |----------|--------| -| **Android** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/android/SKILL.md` | -| **Android 7.x (beta)** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/android/v7/SKILL.md` | +| **Android 6.x** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/android/SKILL.md` | +| **Android 7.x** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/android/v7/SKILL.md` | | **iOS** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/ios/SKILL.md` | | **iOS 7.x (beta)** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/ios/v7/SKILL.md` | | **Flutter** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/flutter/SKILL.md` | diff --git a/docs/ai/agent-skills/sdk/android/SKILL.md b/docs/ai/agent-skills/sdk/android/SKILL.md index 3d69352..fd7f5d2 100644 --- a/docs/ai/agent-skills/sdk/android/SKILL.md +++ b/docs/ai/agent-skills/sdk/android/SKILL.md @@ -1,25 +1,30 @@ --- -title: "Bugsee Android SDK" -name: bugsee-android-sdk -description: Full Bugsee SDK setup for Android. Use when asked to add Bugsee to Android, install bugsee-android, or set up bug reporting, crash reporting, and video recording for Android applications. -sidebar_label: "Android" +title: Bugsee Android SDK 6.x +name: bugsee-android-sdk-6x +description: Bugsee SDK setup for legacy Android 6.x apps. Use only when maintaining an app already on bugsee-android 6.x, or when the user explicitly asks for the 6.x line. For new apps and the current SDK, use bugsee-android-sdk (7.x). +sidebar_label: Android (6.x) sidebar_position: 1 slug: "/ai/agent-skills/sdk/android/SKILL" -license: proprietary +license: MIT category: sdk-setup +generated_from: bugsee-for-ai/skills/bugsee-android-sdk-6x/SKILL.md --- -# Bugsee Android SDK +# Bugsee Android SDK (6.x, Legacy) -Opinionated wizard that scans your Android project and guides you through complete Bugsee setup β€” bug reporting with video, crash reporting, network monitoring, and console logs. +Opinionated wizard for the **6.x** line of the Bugsee Android SDK β€” bug reporting with video, crash reporting, network monitoring, and console logs, using the classic `Bugsee.launch(...)` API (the Gradle plugin is optional on 6.x β€” the 3.x line only uploads symbols; it does no instrumentation). + +> **Legacy.** 7.x is the current Android SDK and the default for new apps β€” use [`bugsee-android-sdk`](https://docs.bugsee.com/ai/agent-skills/sdk/android/v7/SKILL.md) instead. Use this 6.x skill **only** to maintain an app already pinned to `com.bugsee:bugsee-android` 6.x, or when the user explicitly asks for the 6.x line. 7.x is a different, plugin-based SDK with a new API; see the [migration guide](https://docs.bugsee.com/sdk/android/migration/) when upgrading. ## Invoke This Skill When -- User asks to "add Bugsee to Android" or "set up Bugsee" in an Android app -- User wants bug reporting, crash reporting, video recording, or network monitoring in Android -- User mentions `bugsee-android`, `com.bugsee:bugsee-android`, or Bugsee for Kotlin/Java Android +- The user is maintaining an existing app already on `com.bugsee:bugsee-android` 6.x +- The user explicitly asks for Bugsee Android "6.x" / the "legacy" / "old" SDK +- The user's project pins a 6.x version (`com.bugsee:bugsee-android:6.x.y`) and they want to keep it + +For a fresh "add Bugsee to Android" with no 6.x signal, use the current [`bugsee-android-sdk`](https://docs.bugsee.com/ai/agent-skills/sdk/android/v7/SKILL.md) (7.x) skill instead. -> **Note:** Always verify against [docs.bugsee.com/sdk/android/installation/](https://docs.bugsee.com/sdk/android/installation/) before implementing. +> **Note:** Always verify against [docs.bugsee.com/sdk/android/v6/installation/](https://docs.bugsee.com/sdk/android/v6/installation/) before implementing. 6.x docs live under `/sdk/android/v6/`. --- @@ -73,7 +78,7 @@ Add the Bugsee dependency to the app module's build file. ```gradle dependencies { - implementation 'com.bugsee:bugsee-android:+' + implementation 'com.bugsee:bugsee-android:6.0.4' } ``` @@ -81,11 +86,11 @@ dependencies { ```kotlin dependencies { - implementation("com.bugsee:bugsee-android:+") + implementation("com.bugsee:bugsee-android:6.0.4") } ``` -> The `+` fetches the latest version. Pin to a specific version from [release notes](https://docs.bugsee.com/sdk/android/release-notes/) for production stability. +> `6.0.4` is the latest 6.x release β€” pin to it (or another 6.x version from the [6.x release notes](https://docs.bugsee.com/sdk/android/v6/release-notes/)). **Do not** use `+`: that resolves to 7.x, which is the plugin-based SDK with a different API β€” switch to the [`bugsee-android-sdk`](https://docs.bugsee.com/ai/agent-skills/sdk/android/v7/SKILL.md) (7.x) skill for that. If your `compileSdkVersion` is below 29 and you get `android:foregroundServiceType not found`, set `compileSdkVersion` to 29 or higher. @@ -179,7 +184,7 @@ Common options: | `ScreenshotEnabled` | `true` | Attach screenshot to report | | `WifiOnlyUpload` | `false` | Upload only on WiFi | -Full options: [docs.bugsee.com/sdk/android/configuration/](https://docs.bugsee.com/sdk/android/configuration/) +Full options: [docs.bugsee.com/sdk/android/v6/configuration/](https://docs.bugsee.com/sdk/android/v6/configuration/) --- @@ -201,13 +206,48 @@ Check the Bugsee dashboard for the incoming report. --- +## Debug Symbols + +The 6.x line pairs with the **3.x** Gradle plugin (latest **3.6**) β€” never 4.x, which targets the 7.x module layout ([compatibility](https://docs.bugsee.com/sdk/android/gradle-plugin/requirements/)). Plugin 3.x does no bytecode instrumentation; it uploads the R8/ProGuard `mapping.txt` (and, with `ndk(true)`, NDK symbols) on each release build and injects a `BUILD_UUID` into the merged manifest ([6.x Gradle plugin](https://docs.bugsee.com/sdk/android/v6/gradle-plugin/)): + +```kotlin +// app/build.gradle.kts +plugins { + id("com.android.application") + id("com.bugsee.android.gradle") version "3.6" +} + +bugsee { + appToken("") + ndk(true) // only if the app ships native libraries +} +``` + +3.x takes the boolean `ndk(true)`; the nested `ndk { enabled.set(true) }` block is 4.x-only. + +Without the plugin β€” or from CI with no Gradle β€” upload the mapping through the [Bugsee CLI](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-cli/SKILL.md) (or the dashboard's manual upload): + +```bash +bugsee-cli debug-files upload ./app/build/outputs/mapping/release \ + --version 1.4.0 --build 1400 +``` + +`--version` / `--build` must match the shipped build β€” a mismatch uploads a mapping that is accepted and then never resolves a crash. Native NDK symbols go up with `--type elf` and a `--uuid` matching what the SDK reports. + +Upgrading to 7.x moves to plugin 4.x, which adds instrumentation on top of the uploads. + +Full workflow: [`bugsee-upload-symbols`](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-upload-symbols/SKILL.md). + +--- + ## Documentation Links -- [Installation](https://docs.bugsee.com/sdk/android/installation/) -- [Configuration](https://docs.bugsee.com/sdk/android/configuration/) -- [Custom data](https://docs.bugsee.com/sdk/android/v6/custom/) -- [Network events](https://docs.bugsee.com/sdk/android/network/) -- [Console logs](https://docs.bugsee.com/sdk/android/logs/) -- [Privacy](https://docs.bugsee.com/sdk/android/privacy/overview/) -- [Manual invocation](https://docs.bugsee.com/sdk/android/v6/manual/) -- [Release notes](https://docs.bugsee.com/sdk/android/release-notes/) +- [Installation (6.x)](https://docs.bugsee.com/sdk/android/v6/installation/) +- [Configuration (6.x)](https://docs.bugsee.com/sdk/android/v6/configuration/) +- [Custom data (6.x)](https://docs.bugsee.com/sdk/android/v6/custom/) +- [Network events (6.x)](https://docs.bugsee.com/sdk/android/v6/network/) +- [Console logs (6.x)](https://docs.bugsee.com/sdk/android/v6/logs/) +- [Privacy (6.x)](https://docs.bugsee.com/sdk/android/v6/privacy/overview/) +- [Manual invocation (6.x)](https://docs.bugsee.com/sdk/android/v6/manual/) +- [Release notes (6.x)](https://docs.bugsee.com/sdk/android/v6/release-notes/) +- [Migrate to 7.x](https://docs.bugsee.com/sdk/android/migration/) diff --git a/docs/ai/agent-skills/sdk/android/v7/SKILL.md b/docs/ai/agent-skills/sdk/android/v7/SKILL.md index 1df0261..5978aeb 100644 --- a/docs/ai/agent-skills/sdk/android/v7/SKILL.md +++ b/docs/ai/agent-skills/sdk/android/v7/SKILL.md @@ -1,33 +1,36 @@ --- -title: "Bugsee Android SDK 7.x (Beta)" -name: bugsee-android-sdk-7x -description: Full Bugsee 7.x (beta) setup for Android. Use when the user explicitly asks for Bugsee Android 7.x / beta, or wants the next-gen features (APM, extension modules, auto-init, new detection providers). For stable production setup, use the 6.x skill instead. -sidebar_label: "Android (7.x Beta)" +title: Bugsee Android SDK 7.x +name: bugsee-android-sdk +description: Full Bugsee SDK setup for Android (7.x β€” the current SDK). Use when asked to add Bugsee to Android, install bugsee-android, or set up bug reporting, crash reporting, video recording, APM, or network monitoring for Android apps. For legacy 6.x apps, use bugsee-android-sdk-6x. +sidebar_label: Android (7.x) sidebar_position: 2 slug: "/ai/agent-skills/sdk/android/v7/SKILL" -license: proprietary +license: MIT category: sdk-setup +generated_from: bugsee-for-ai/skills/bugsee-android-sdk/SKILL.md --- -# Bugsee Android SDK 7.x (Beta) +# Bugsee Android SDK -Opinionated wizard that scans the Android project and wires up Bugsee 7.x β€” core SDK, Gradle plugin, extension modules for network clients / Compose / feedback, APM, and manifest-based auto-launch. +Opinionated wizard that scans the Android project and wires up Bugsee 7.x β€” core SDK, Gradle plugin, extension modules for network clients / Compose / feedback / NDK, APM, and manifest-based auto-launch. -> **Beta warning.** 7.x is in active beta. Option keys, module names, and internal APIs may still change. For production apps shipping today, prefer the stable [6.x skill](/ai/agent-skills/sdk/android/SKILL). Continue only if the user explicitly asks for 7.x / beta, or needs APM, Ktor/Cronet capture, manifest auto-launch, the Gradle plugin, or individual `bugsee-android-*` artifacts. +> **7.x is the current Android SDK** (`com.bugsee:bugsee-android:7.3.0`, Gradle plugin `com.bugsee.android.gradle` / `com.bugsee:bugsee-android-gradle-plugin:4.0.7`, re-verified 2026-09-30 on Maven Central and Plugin Portal; SDK lastUpdated 2026-09-29, plugin 2026-09-19) and the default for new and existing apps. Keep the two pins paired β€” the plugin's Compose launch crash fix (4.0.6+) requires SDK 7.1.4+; **7.3.0** satisfies that. **Never pin plugin 4.0.6** β€” it silently disables every SDK extension (see Phase 2). Plugin latest is still **4.0.7** (no 4.0.8+ on either registry; 7.3.0 does not require a plugin bump). 7.3.0 is a security/reliability release β€” upgrade apps on 7.0.0-beta1 through 7.2.0. It is plugin-based with a new API. If you are maintaining an app still pinned to the 6.x line, use the legacy [6.x skill](https://docs.bugsee.com/ai/agent-skills/sdk/android/SKILL.md) instead; when upgrading from 6.x, follow the [migration guide](https://docs.bugsee.com/sdk/android/migration/). ## Invoke This Skill When -- User explicitly says "Bugsee 7.x", "beta", "next-gen Bugsee", or `7.0.0-beta*`. +- User asks to "add Bugsee to Android" or "set up Bugsee" / bug reporting / crash reporting / video recording in an Android app (Kotlin or Java). +- User mentions `bugsee-android`, `com.bugsee:bugsee-android`, or the **Bugsee Gradle plugin** (`com.bugsee.android.gradle`). - User mentions **APM**, transactions, or spans (`Bugsee.startTransaction`, `startSpan`). -- User mentions **extension modules** (`bugsee-android-okhttp`, `bugsee-android-ktor-2`, `bugsee-android-ktor-3`, `bugsee-android-cronet`, `bugsee-android-compose`, `bugsee-android-feedback`). +- User mentions **extension modules** (`bugsee-android-okhttp`, `bugsee-android-ktor-2`, `bugsee-android-ktor-3`, `bugsee-android-cronet`, `bugsee-android-compose`, `bugsee-android-feedback`, `bugsee-android-ndk`, `bugsee-android-leak`). - User asks for **manifest auto-launch** / no Application subclass. -- User mentions the **Bugsee Gradle plugin** (`com.bugsee.android.gradle`). -- User asks about **Compose secure modifier**, `Modifier.bugseeSecure()`, Ktor / Cronet / `HttpEngine` integration. -- User mentions new detection providers: `DetectAndReportMainThreadMisuse`, `DetectAndReportExit*`, `DetectAndReportEarlyCrash`. +- User asks about **Compose secure modifier**, `Modifier.bugseeSecure()`, Ktor / Cronet / `HttpEngine` integration, **WebSocket** capture, **`FLAG_SECURE`**, or `Bugsee.getStatus()`. +- User mentions detection providers: `DetectAndReportMainThreadMisuse`, `DetectAndReportExit*`, `DetectAndReportEarlyCrash`, `DetectAndReportHangSampling`, `DetectAndReportAnrSampling`. +- User mentions **`Bugsee.notify()`**, notification relay, or sending a message to Slack/Teams without creating an issue. +- User mentions **pending-report caps** (`MaxDataSize`, `MaxPendingReports`, `MaxPendingReportAge`), **`Bugsee.getDefaultNetworkSanitizer()`**, **`Bugsee.getHostLaunchOptions()`**, or a **`ReportHandler`** that touches UI. -For generic "add Bugsee to Android" / "set up bug reporting" with no 7.x signal, switch to the 6.x skill. +For an app explicitly pinned to the **6.x** line (or when the user asks for "6.x" / the "legacy" SDK), switch to the [6.x skill](https://docs.bugsee.com/ai/agent-skills/sdk/android/SKILL.md). -> **Always verify against** [docs.bugsee.com/sdk/android/installation/](https://docs.bugsee.com/sdk/android/installation/) before implementing. 7.x docs live under `/sdk/android/`; `/sdk/android/v6/` is the legacy 6.x tree. +> **Always verify against** [docs.bugsee.com/sdk/android/installation/](https://docs.bugsee.com/sdk/android/installation/) before implementing. Prefer Maven/Plugin Portal versions over the installation page's placeholders when they disagree. --- @@ -54,6 +57,10 @@ grep -rE 'com\.squareup\.okhttp3|io\.ktor:ktor-client|org\.chromium\.net|okhttp3 # Compose? grep -rE 'androidx\.compose|@Composable' app/build.gradle* app/src 2>/dev/null | head -5 +# Native / NDK? +ls app/src/main/cpp app/src/main/jni 2>/dev/null +grep -rE 'ndk|externalNativeBuild|cmake' app/build.gradle* 2>/dev/null | head -5 + # Application subclass + manifest (for programmatic-vs-auto-launch decision) grep -r "extends Application\|: Application()" app/src/main --include="*.java" --include="*.kt" 2>/dev/null | head -3 grep -E 'android:name=|/dev/null | head -5 @@ -67,12 +74,13 @@ Decision table: | `minSdk` < 21 | **Stop** β€” 7.x requires `minSdk = 21`. | | `build.gradle.kts` present | Use Kotlin DSL snippets below. | | `build.gradle` (Groovy) | Use Groovy snippets. | -| OkHttp 3/4 detected | Plugin auto-installs `bugsee-android-okhttp`; no manual wiring. | -| OkHttp 2 only | Not supported in 7.x β€” user must migrate to OkHttp 3/4 or drop to 6.x. | -| Ktor 2.x / 3.x detected | Plugin auto-installs extension, but user must `install(BugseeKtor2Plugin)` / `install(BugseeKtor3Plugin.Plugin)` on every `HttpClient`. | +| OkHttp 3/4 detected | Plugin auto-installs `bugsee-android-okhttp`; no manual wiring. WebSocket via `OkHttpClient.newWebSocket(...)` is captured automatically (plugin **4.0.3+**). | +| OkHttp 2 only | Not supported in 7.x β€” user must migrate to OkHttp 3/4 or use the [6.x skill](https://docs.bugsee.com/ai/agent-skills/sdk/android/SKILL.md). | +| Ktor 2.x / 3.x detected | Plugin auto-installs extension, but user must `install(BugseeKtor2Plugin)` / `install(BugseeKtor3Plugin.Plugin)` on every `HttpClient`. WebSocket on the OkHttp engine is automatic; on CIO, route calls through the `bugseeWebSocket` helper (plugin 4.0.3+). | | Cronet detected | Plugin auto-installs extension, but user must wrap every engine with `BugseeCronet.instrument(engine)`. | | Compose detected | Plugin auto-installs `bugsee-android-compose` + Kotlin compiler plugin (secure modifier + input capture). | -| Feedback UI wanted | Manually add `bugsee-android-feedback` β€” **not** auto-installed. | +| Native / NDK code | Enable `ndk { enabled.set(true) }` β€” pulls `bugsee-android-ndk`. | +| Feedback UI wanted | `feedback.set(true)` β€” **not** auto-installed from other dependencies. | | No Application subclass | Prefer manifest auto-launch (Phase 3 Option A). | --- @@ -81,7 +89,7 @@ Decision table: ### Step 1 β€” Apply the Bugsee Gradle plugin (mandatory) -7.x requires the plugin. Without it, APM, main-thread misuse detection, log capture rewrites, OkHttp injection, and Compose secure redaction do not work. +7.x requires the plugin. Without it, APM, main-thread misuse detection, log capture rewrites, OkHttp injection, and Compose secure redaction do not work. Pin plugin **4.0.7** with SDK **7.3.0** (plugin still the current Plugin Portal / Maven release as of 2026-09-30; keep the two pins paired). Plugin 4.x pairs with SDK 7.x; do not mix with plugin 3.x / SDK 6.x. There is no separate Gradle-plugin skill β€” apply the notes below from the [plugin release notes](https://docs.bugsee.com/sdk/android/gradle-plugin/releases/). **Kotlin DSL (`app/build.gradle.kts`):** @@ -89,19 +97,25 @@ Decision table: plugins { id("com.android.application") id("org.jetbrains.kotlin.android") - id("com.bugsee.android.gradle") version "7.0.0-beta3" + id("com.bugsee.android.gradle") version "4.0.7" } bugsee { appToken("") + // In-app feedback messenger UI (default: off) β€” plugin pulls bugsee-android-feedback + // feedback.set(true) + // Native crash capture + NDK symbol upload (default: off) β€” plugin pulls bugsee-android-ndk // ndk { - // enabled.set(true) // upload NDK symbols for native crash symbolication + // enabled.set(true) // // forceDebugSymbolsUpload.set(true) // re-upload even when the build UUID hasn't changed // } + // Memory & thread leak detection (default: off) β€” plugin pulls bugsee-android-leak + // leak { enabled.set(true) } // instrumentation { // mainThreadMisuse.set(false) // disable any individual hook if needed // ktor.set(false) // suppress auto-install of an extension // } + // Do not disable mainThreadMisuse / log / thread / operationDispatch just to unbreak JVM unit tests β€” SDK 7.1.4+ keeps those tests passing with instrumentation on. } ``` @@ -111,14 +125,12 @@ bugsee { plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' - id 'com.bugsee.android.gradle' version '7.0.0-beta3' + id 'com.bugsee.android.gradle' version '4.0.7' } bugsee { appToken '' - // ndk { - // enabled.set true - // } + // ndk { enabled.set true } } ``` @@ -134,15 +146,28 @@ pluginManagement { } ``` -### Step 2 β€” Add the core artifact +With the plugin applied, the core `com.bugsee:bugsee-android` artifact is auto-pulled (bounded to the same MAJOR.MINOR series as the plugin's `sdk-min-version`). Dependency-driven extensions (OkHttp, Ktor 2/3, Cronet, Compose) are auto-installed when the matching library is in the graph. Feedback, NDK, and leak are **not** dependency-driven β€” enable them with the DSL toggles above. + +From plugin **4.0.6** (carried into 4.0.7): variants that do **not** include Bugsee (e.g. `debugImplementation` only) are no longer instrumented or wired. Flavors are handled the same way. Plain `implementation` is unchanged β€” do not invent extra plugin flags for that case. The Compose launch crash fix requires SDK **7.1.4+**; **7.3.0** satisfies that β€” do not pair plugin 4.0.6+ with an older 7.1.x SDK. No DSL changes. Plugin latest is still **4.0.7** (Maven Central / Plugin Portal lastUpdated 2026-09-19; re-verified 2026-09-30). + +> **Plugin 4.0.6 is broken β€” upgrade it on sight.** In apps built against the published SDK, 4.0.6 stripped the extension providers from the manifest without registering the extensions in their place: **NDK crash reporting, feedback, Compose, OkHttp, Ktor, Cronet and leak detection never ran**, with a green build and a normally working app. Because the Compose extension never installed, content marked `bugseeSecure` was **not masked** in report screenshots. 4.0.7 fixes it. If an app is on 4.0.6 and cannot move yet, stay on 4.0.5 or set `optimizeExtensionsLoading.set(false)` in `bugsee {}`. Also in 4.0.7 ([release notes](https://docs.bugsee.com/sdk/android/gradle-plugin/releases/)): +> - Only Bugsee's own extension providers are consolidated β€” a `BugseeInitProvider` in the app or a wrapper SDK is no longer silently removed (4.0.0-beta10 β†’ 4.0.6 removed them). +> - If the plugin would strip extension providers it cannot register (e.g. an SDK older than 7.0.0-beta11 declared with a non-literal version such as `7.+`), the build now **fails** naming the providers and pointing at `optimizeExtensionsLoading` β€” that error means "pin a literal SDK version", not "disable the plugin". +> - The built-in fallback uploader treats the server's "already uploaded" reply as success, so an unchanged mapping is no longer re-uploaded on every build. +> - The auto-added SDK floor is still 7.2.0 (plugin 4.0.7). Auto-pull on `[7.2.0,8.0.0)` can resolve 7.3.0, but pin **7.3.0** explicitly so the security release is locked. + +### Step 2 β€” Pin the core SDK (recommended) + +An explicit `com.bugsee:bugsee-android` declaration wins over auto-pull and locks the runtime. Pin **7.3.0**. Avoid `+`. **Kotlin DSL:** ```kotlin dependencies { - implementation("com.bugsee:bugsee-android:7.0.0-beta3") - // Feedback UI is NOT auto-installed. Add it if the user wants the feedback flow: - // implementation("com.bugsee:bugsee-android-feedback:7.0.0-beta3") + implementation("com.bugsee:bugsee-android:7.3.0") + // Only if you did not use feedback.set(true) / ndk { enabled.set(true) } and need a manual pin: + // implementation("com.bugsee:bugsee-android-feedback:7.3.0") + // implementation("com.bugsee:bugsee-android-ndk:7.3.0") } ``` @@ -150,14 +175,27 @@ dependencies { ```groovy dependencies { - implementation 'com.bugsee:bugsee-android:7.0.0-beta3' - // implementation 'com.bugsee:bugsee-android-feedback:7.0.0-beta3' + implementation 'com.bugsee:bugsee-android:7.3.0' } ``` -The plugin auto-adds `bugsee-android-okhttp`, `bugsee-android-ktor-2`, `bugsee-android-ktor-3`, `bugsee-android-cronet`, and `bugsee-android-compose` when it detects the matching dependency in the graph. To suppress any of these, set the corresponding flag in the `bugsee { instrumentation { ... } }` block (e.g. `cronet.set(false)`). - -> 7.0.0-beta3 is the latest beta at the time of writing. Pin to a concrete version; avoid `+`. +To suppress auto-install of a dependency-driven extension, set the corresponding flag in `bugsee { instrumentation { ... } }` (e.g. `cronet.set(false)`). To opt out of core auto-pull entirely, `sdkAutoLoad.set(false)`. + +> **Current stable releases (re-verified 2026-09-30 against Maven Central and Plugin Portal; SDK lastUpdated 2026-09-29):** SDK `com.bugsee:bugsee-android:7.3.0` (and matching `bugsee-android-compose`, `bugsee-android-ndk`, `bugsee-android-feedback`, `bugsee-android-okhttp`, `bugsee-android-ktor-2`, `bugsee-android-ktor-3`, `bugsee-android-cronet`, `bugsee-android-leak` at **7.3.0**) and Gradle plugin `4.0.7` (`com.bugsee:bugsee-android-gradle-plugin` / Plugin Portal `com.bugsee.android.gradle`; plugin lastUpdated 2026-09-19). The plugin tracks its own 4.x line, separate from the SDK β€” pin both together. 7.3.0 does not require a plugin bump. +> +> **SDK 7.3.0 / plugin 4.0.7 β€” cite, do not invent APIs.** [Android SDK 7.3.0](https://docs.bugsee.com/sdk/android/release-notes/) is a security and reliability release; the public API is **additive**. [Gradle plugin 4.0.7](https://docs.bugsee.com/sdk/android/gradle-plugin/releases/) remains the latest fix release β€” no DSL changes. Agents should **not** advise workarounds 7.1.4 / 4.0.6 made unnecessary: +> - **Upgrade from 7.2.0 (and any 7.0.0-beta1+).** The SDK internal log attached to reports no longer records app HTTP URLs (including embedded credentials and query strings), `setUserIdentifier` / `setAttribute` values, performance-transaction URLs, or filter/listener text. Data written by an earlier 7.x is deleted on the first 7.3.0 launch and never attached. Recommend the upgrade; do not invent a third-party leak β€” it stayed in the app's own Bugsee project. +> - **Ktor.** 7.2.0 `bugsee-android-ktor-2` / `bugsee-android-ktor-3` did not compile `install(BugseeKtor2Plugin)`, `install(BugseeKtor3Plugin.Plugin)`, or `bugseeWebSocket` in Kotlin apps. Pin **7.3.0**. +> - **Pending-report caps (defaults on).** `MaxDataSize` (150 MB), `MaxPendingReports` (30), `MaxPendingReportAge` (30 days). Past a limit, oldest unsent reports are deleted (errors before bugs before crashes). A device offline more than 30 days now drops the oldest instead of keeping them all. +> - **ReportHandler.** Handlers no longer run on the main thread (they now also run for hang/ANR). If a handler touches views, post to the main thread. With `ReportHandlerCallbackTimeout` `0`, a handler that never completes no longer holds the report indefinitely. +> - **`Bugsee.logException(null)`.** Now reports a simulated exception from the call site (groups by call site, not one empty issue). +> - **Network sanitizer.** Use `Bugsee.getDefaultNetworkSanitizer().sanitize(event)` inside a custom network filter to keep built-in redaction. Static `com.bugsee.library.shared.security.privacy.NetworkDataSanitizer` is deprecated; if both that package and `com.bugsee.library.contracts.exchange.*` are wildcard-imported, import one by name. +> - **JVM unit tests.** 7.1.4+ stops Bugsee from failing ordinary JVM unit tests. If someone disabled `mainThreadMisuse` / `log` / `thread` / `operationDispatch` instrumentation only to get a green test run, they can turn those back on. +> - **Host logging.** Logging statements in the host app are unaffected by failures inside Bugsee capture. +> - **Report UI / notifications.** Crash when the report screen is restored after process death; crash on light/dark theme change while a notification-opened report is on screen; Huawei Android 6 notification small-icon fallback; screenshot loss on some storage configs. +> - **Variant / flavor wiring (4.0.6+).** Variants (and flavors) that do not include Bugsee are left uninstrumented. Plain `implementation` is unchanged. +> - **Compose.** The Compose launch crash fix **requires SDK 7.1.4+**. **7.3.0** satisfies that. Keep the two pins paired. +> - **Instrumentation / APM.** Thread-instrumentation crash fix; failed DB/file operations are now timed (host exception handling unchanged). Manifest optimization is applied only when the SDK version supports it; already-minified third-party libraries are left as-is. --- @@ -180,14 +218,14 @@ No Application subclass needed, no `Bugsee.launch(...)` call. Add the token as ` The SDK launches automatically at process start via `BugseeInitProvider`. Any option can be set via manifest metadata using the `com.bugsee.option..` key; enums take the value name as a string (e.g. `"High"` for `FrameRate.High`). ```xml - + ``` ### Option B β€” Programmatic launch -Use when the token is fetched at runtime or options need dynamic values. Context is auto-discovered. +Use when the token is fetched at runtime or options need dynamic values. Context is auto-discovered. If the token is also in the manifest, disable auto-init with `com.bugsee.auto-init` = `false`. **Kotlin:** @@ -200,13 +238,15 @@ class MyApplication : Application() { super.onCreate() val options = hashMapOf( Options.Duration to 60, - Options.DetectAndReportCrashNdk to true + Options.CaptureVideoAdaptive to true ) Bugsee.launch(this, "", options) } } ``` +Shortest form (context resolved automatically): `Bugsee.launch("")`. + **Java:** ```java @@ -218,35 +258,101 @@ public class MyApplication extends Application { super.onCreate(); HashMap options = new HashMap<>(); options.put(Options.Duration, 60); - options.put(Options.DetectAndReportCrashNdk, true); + options.put(Options.CaptureVideoAdaptive, true); Bugsee.launch(this, "", options); } } ``` -Options passed to `launch(...)` override manifest metadata. The 6.x `LaunchOptions` builder is removed. There is no shortest-form `Bugsee.launch(token)` β€” pass context (or use manifest auto-launch). +A `Map` passed to `launch(...)` is a **full override**, not a merge with manifest metadata: any key left out of the map falls back to its registered default, not to the manifest value. The 6.x `LaunchOptions` builder is removed. --- ## Phase 4: Configure (Optional) -All configuration flows through either (a) manifest `` entries, or (b) the `Map` passed to `Bugsee.launch(...)`. Keys live on `com.bugsee.library.contracts.options.Options`. +All configuration flows through either (a) manifest `` entries, or (b) the `Map` passed to `Bugsee.launch(...)`. Keys live on `com.bugsee.library.contracts.options.Options`. Canonical table: [configuration](https://docs.bugsee.com/sdk/android/configuration/). -Common toggles: +Common toggles (including 7.1.x / 7.2.0 / 7.3.0 setup-relevant options): | `Options` constant | Manifest key | Default | Description | |---|---|---|---| | `Duration` | `com.bugsee.option.config.duration` | `60` | Video ring buffer duration (seconds). | | `WifiOnlyUpload` | `com.bugsee.option.config.wifi-only-upload` | `false` | Restrict uploads to Wi-Fi. | -| `DetectAndReportCrashNdk` | `com.bugsee.option.detect.crash-ndk` | `false` | Enable Breakpad native crash capture. | +| `NotifyFlushDelay` | `com.bugsee.option.config.notify-flush-delay` | `0` | **7.2.0.** Coalescing window (ms) before the non-urgent `Bugsee.notify()` queue drains. `0` starts the drain as soon as a notification is persisted. Does not affect an urgent skip-ahead POST. | +| `MaxDataSize` | `com.bugsee.option.config.max-data-size` | `150` | **7.3.0.** Cap on unsent report data on device (MB, minimum `10`). Past a limit, oldest reports are deleted. | +| `MaxPendingReports` | `com.bugsee.option.config.max-pending-reports` | `30` | **7.3.0.** Max unsent reports (minimum `1`). | +| `MaxPendingReportAge` | `com.bugsee.option.config.max-pending-report-age` | `30` | **7.3.0.** Max age of unsent reports in days. `0` or less turns aging off. | | `DetectAndReportHang` | `com.bugsee.option.detect.hang` | `false` | Main-thread hang detection. | +| `DetectAndReportHangSampling` | `com.bugsee.option.detect.hang.sampling` | `true` | **7.2.0.** Sample the main thread during a hang and attribute the report to the culprit stack. Takes effect only when `DetectAndReportHang` is enabled. | | `DetectAndReportMainThreadMisuse` | `com.bugsee.option.detect.main_thread_misuse` | `false` | Flag I/O / network / DB / `SharedPreferences` on main thread. Requires plugin `mainThreadMisuse` instrumentation. | -| `DetectAndReportExit` | `com.bugsee.option.detect.exit` | `false` | Master switch for `ApplicationExitInfo`-based exit reports. | +| `DetectAndReportExit` | `com.bugsee.option.detect.exit` | `true` | Master switch for `ApplicationExitInfo`-based exit reports (7.1 default). | +| `DetectAndReportAnrSampling` | `com.bugsee.option.detect.anr.sampling` | `true` | **7.2.0.** Sample the main thread during an ANR and attribute the report to the culprit stack. Takes effect only when `DetectAndReportExitNotResponding` is enabled. | +| `DetectAndReportExitLowMemoryBackgroundAsError` | `com.bugsee.option.detect.exit.bg_low_memory_as_error` | `false` | **7.3.0.** Report a background low-memory kill as a non-fatal error instead of a crash. Foreground kills stay crashes. | | `CaptureVideoFrameRate` | `com.bugsee.option.capture.video.frame-rate` | `High` | `Low` / `Medium` / `High`. | +| `CaptureVideoAdaptive` | `com.bugsee.option.capture.video.adaptive` | `false` | **7.1.0.** Skip capturing new frames while nothing on screen has been redrawn (at least one frame per second). Lowers CPU/battery on idle screens. | +| `CaptureNetworkOnLaunch` | `com.bugsee.option.capture.network.on-launch` | `false` | **7.1.0.** Subscribe the network provider during `launch()` instead of when capture starts, so startup requests are not missed. | +| `CaptureRespectFlagSecure` | `com.bugsee.option.capture.respect-flag-secure` | `true` | **7.1.0.** Honor `WindowManager.LayoutParams.FLAG_SECURE`: those windows are blanked in video and screenshots, excluded from the view hierarchy, and their input is dropped. An app that sets `FLAG_SECURE` broadly will see empty recordings after upgrading β€” set to `false` to restore pre-7.1.0 behavior. | | `ReportingTriggerByShake` | `com.bugsee.option.reporting.triggers.shake` | `true` | Shake-to-report gesture. | | `PerformanceMonitoring` | `com.bugsee.option.performance.enabled` | `true` | APM master switch. | | `PerformanceSampleRate` | `com.bugsee.option.performance.sample-rate` | `0.01` | Standalone-upload probability per transaction (capture is unaffected). | +### NDK native crashes (`bugsee-android-ndk`) + +Native crash detection is **not** in the core artifact. Enable it with the plugin DSL (`ndk { enabled.set(true) }`) or `implementation("com.bugsee:bugsee-android-ndk:7.3.0")`. The programmatic constant is `NdkOptions.DetectAndReport` (`com.bugsee.library.ndk.contracts.options.NdkOptions`), **not** the removed `Options.DetectAndReportCrashNdk`. Manifest key `com.bugsee.option.detect.crash-ndk` is unchanged; default is `true` once the module is on the classpath. See [native crashes](https://docs.bugsee.com/sdk/android/issue-detection/native-crashes/). + +### WebSocket + +OkHttp `newWebSocket(...)` traffic (connection lifecycle, frames, close/error) is captured automatically when the OkHttp extension is installed (Gradle plugin **4.0.3+**; use 4.0.7 β€” 4.0.6 never registered the OkHttp extension). Ktor on the OkHttp engine is automatic; on CIO, route calls through the `bugseeWebSocket` helper. `NetworkEventStage.WebSocket` is the stage value for custom events. + +### `FLAG_SECURE` + +Windows that set `FLAG_SECURE` (including payment/DRM surfaces that set it for you) are protected by default since 7.1.0 via `CaptureRespectFlagSecure`. See [privacy / video](https://docs.bugsee.com/sdk/android/privacy/video/). + +### `Bugsee.notify()` (7.2.0) + +Sends a title (required; empty title is a no-op), optional body, optional `IssueSeverity`, and optional `Map` extra rows to the app's configured Slack/Teams/webhook integrations **without** creating an issue or running the report pipeline. No-op if the SDK has not launched (not buffered). Queued to disk and delivered in batches while offline; payloads larger than 256 KiB are rejected. The five-argument overload's `urgent` flag attempts an immediate skip-ahead POST when the call is in the main process, a session is active, and the network is reachable (honoring `WifiOnlyUpload`); otherwise it queues like a non-urgent call. Tune batching with `NotifyFlushDelay` (default `0`). Full contract: [notification relay](https://docs.bugsee.com/sdk/android/notification-relay/). + +```kotlin +import com.bugsee.library.Bugsee +import com.bugsee.library.contracts.options.IssueSeverity + +Bugsee.notify("Payment webhook failed") +Bugsee.notify("Payment webhook failed", "returned 500 for order 42", IssueSeverity.High) + +val fields = linkedMapOf("order_id" to "42", "status_code" to "500") +Bugsee.notify("Payment webhook failed", "returned 500 for order 42", IssueSeverity.Critical, fields, true) +``` + +### Hang / ANR culprit-stack sampling (7.2.0) + +When hang or ANR detection is on, the SDK samples the main thread for the duration of the freeze and uses the derived culprit stack as the report signature (the original stack still travels in the thread list). Controlled by `DetectAndReportHangSampling` and `DetectAndReportAnrSampling` β€” both **on by default**, and each takes effect only when its parent is enabled (`DetectAndReportHang` / `DetectAndReportExitNotResponding`). Existing hang and ANR issues regroup once after upgrade. Background ANRs on API 30+ keep the old single-snapshot stack for now. + +### View hierarchy v3 (7.2.0) + +The captured view-hierarchy document is version 3: every window on the display (dialogs, popups, toasts, …), a root `display` object (size, rotation, insets, cutouts), `window_kind`, Z-order, and richer per-node fields (layout id, `clip_children`, background color). Other exported streams stay at version 2. No new `Options` toggle β€” `CaptureViewHierarchy` is unchanged. + +### SDK 7.3.0 β€” agent notes + +- **Pending-report caps are on by default.** Raise or disable them only if the app must retain a long offline queue; otherwise leave the defaults. Deletion order is errors, then bug reports, then crashes; the newest crash and in-flight uploads are kept. +- **Report handlers and UI.** `ReportHandler` runs off the main thread. Post view work with `Handler(Looper.getMainLooper())`. Crash handling can still occasionally invoke the handler on the main thread β€” keep it short. `Report.addAttachment(File, name, mimeType, move)` (and the `byte[]` overload) add files without loading them into memory; both return `null` if the report is already submitted. `Report.setScreenshot(displayId, bitmap, annotated)` / `isScreenshotAnnotated(displayId)` mark user-drawn screenshots; only annotated ones show as annotations on the issue. +- **Launch map enums.** Pass enum options by name in the launch `Map` (e.g. `"High"` for `VideoQuality`), matched case-insensitively like the manifest. Before 7.3.0 a string value was accepted but ignored. +- **`Bugsee.getHostLaunchOptions()`** returns options the app supplied (launch map or manifest) without SDK defaults. `Bugsee.getLaunchOptions()` still returns the options in effect. +- **Custom network events.** If you build events with `Bugsee.getExchangeFactory()`, stamp them with `BugseeExchangeFactory.currentTimestamp()` β€” clock changes no longer drop events. + +### `Bugsee.getStatus()` + +```kotlin +import com.bugsee.library.contracts.lifecycle.BugseeStatus + +when (Bugsee.getStatus()) { + BugseeStatus.Launched -> { /* running */ } + BugseeStatus.Launching, BugseeStatus.Stopping -> { /* in transition */ } + BugseeStatus.Stopped -> { /* not running */ } +} +``` + +`Bugsee.getLaunched()` remains the boolean shortcut (`true` between a successful launch/auto-init and the next `stop()`). See [lifecycle](https://docs.bugsee.com/sdk/android/lifecycle/). + Network client wiring (required for non-OkHttp clients): - **OkHttp 3/4** β€” transparent; plugin injects `BugseeOkHttpInterceptor` into every `OkHttpClient.Builder.build()`. No code changes. @@ -279,12 +385,37 @@ Check the Bugsee dashboard for the incoming report. If APM is enabled, hit a few --- +## Debug Symbols + +The Bugsee Gradle plugin applied in Phase 2 already uploads the R8/ProGuard `mapping.txt` on each release build, and NDK symbols when `ndk { enabled.set(true) }` is set. **For a Gradle project that is the whole answer** β€” nothing else to wire. + +Outside Gradle β€” a prebuilt APK, or a CI job that only has the artifacts β€” upload with the [Bugsee CLI](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-cli/SKILL.md): + +```bash +bugsee-cli debug-files upload ./app/build/outputs/mapping/release \ + --version 1.4.0 --build 1400 +``` + +`--version` / `--build` must match the shipped build, or the symbol is accepted and never resolves a crash. + +Full workflow: [`bugsee-upload-symbols`](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-upload-symbols/SKILL.md) Β· [Gradle plugin](https://docs.bugsee.com/sdk/android/gradle-plugin/). + +--- + ## Documentation Links -- [Installation (7.x)](https://docs.bugsee.com/sdk/android/installation/) -- [Configuration (7.x)](https://docs.bugsee.com/sdk/android/configuration/) -- [Gradle plugin (7.x)](https://docs.bugsee.com/sdk/android/gradle-plugin/) -- [Network events (7.x)](https://docs.bugsee.com/sdk/android/network/) -- [Issue detection (7.x)](https://docs.bugsee.com/sdk/android/issue-detection) -- [Performance / APM (7.x)](https://docs.bugsee.com/sdk/android/performance/) +- [Installation](https://docs.bugsee.com/sdk/android/installation/) +- [Configuration](https://docs.bugsee.com/sdk/android/configuration/) +- [NDK options](https://docs.bugsee.com/sdk/android/configuration/ndk/) +- [Gradle plugin](https://docs.bugsee.com/sdk/android/gradle-plugin/) +- [SDK release notes](https://docs.bugsee.com/sdk/android/release-notes/) +- [Gradle plugin releases](https://docs.bugsee.com/sdk/android/gradle-plugin/releases/) +- [Network events](https://docs.bugsee.com/sdk/android/network/) +- [Issue detection](https://docs.bugsee.com/sdk/android/issue-detection/) +- [Native crashes](https://docs.bugsee.com/sdk/android/issue-detection/native-crashes/) +- [Privacy / video (`FLAG_SECURE`)](https://docs.bugsee.com/sdk/android/privacy/video/) +- [Privacy / network (`getDefaultNetworkSanitizer`)](https://docs.bugsee.com/sdk/android/privacy/network/) +- [Notification relay / `Bugsee.notify()`](https://docs.bugsee.com/sdk/android/notification-relay/) +- [Lifecycle / `getStatus`](https://docs.bugsee.com/sdk/android/lifecycle/) +- [Performance / APM](https://docs.bugsee.com/sdk/android/performance/) - [Migration from 6.x](https://docs.bugsee.com/sdk/android/migration/) diff --git a/docs/ai/agent-skills/sdk/cordova/SKILL.md b/docs/ai/agent-skills/sdk/cordova/SKILL.md index 9dcb9c4..06e5805 100644 --- a/docs/ai/agent-skills/sdk/cordova/SKILL.md +++ b/docs/ai/agent-skills/sdk/cordova/SKILL.md @@ -1,12 +1,13 @@ --- -title: "Bugsee Cordova SDK" +title: Bugsee Cordova SDK name: bugsee-cordova-sdk description: Full Bugsee SDK setup for Cordova. Use when asked to add Bugsee to Cordova, install bugsee cordova plugin, or set up bug reporting, crash reporting, and video recording for Cordova applications. -sidebar_label: "Cordova" +sidebar_label: Cordova sidebar_position: 8 slug: "/ai/agent-skills/sdk/cordova/SKILL" -license: proprietary +license: MIT category: sdk-setup +generated_from: bugsee-for-ai/skills/bugsee-cordova-sdk/SKILL.md --- # Bugsee Cordova SDK @@ -51,12 +52,14 @@ ls platforms 2>/dev/null ## Phase 2: Install ```bash -cordova plugin add com.bugsee.cordova-plugin --save +cordova plugin add com.bugsee.cordova-plugin@7.0.1 --save # Optional: install device plugin for platform detection cordova plugin add cordova-plugin-device --save ``` +Current npm latest (re-verified 2026-08-25): **7.0.1**. Pin it rather than leaving the add unversioned. + --- ## Phase 3: Initialize @@ -119,6 +122,25 @@ The Bugsee floating button should appear. Tap it to file a test bug report, then --- +## Debug Symbols + +A Cordova crash can land in the web layer or the native one, and each needs its own symbols. + +**JavaScript β€” source maps**, via the [Bugsee CLI](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-cli/SKILL.md): + +```bash +npm i -D @bugsee/cli@0.8.1 +npx bugsee-cli sourcemaps inject +npx bugsee-cli debug-files upload --type sourcemaps \ + --version 1.4.0 --build 1400 +``` + +Point both at whatever directory the web build emits its bundles and `.map` files into. `inject` must run after the bundler and before the upload, on the same output. + +**Native.** iOS needs dSYMs, Android the R8/ProGuard mapping β€” see [`bugsee-upload-symbols`](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-upload-symbols/SKILL.md) for both. + +--- + ## Documentation Links - [Installation](https://docs.bugsee.com/sdk/cordova/installation/) diff --git a/docs/ai/agent-skills/sdk/dotnet/SKILL.md b/docs/ai/agent-skills/sdk/dotnet/SKILL.md index 2045353..b2c01c8 100644 --- a/docs/ai/agent-skills/sdk/dotnet/SKILL.md +++ b/docs/ai/agent-skills/sdk/dotnet/SKILL.md @@ -1,12 +1,13 @@ --- -title: "Bugsee .NET SDK" +title: Bugsee .NET SDK name: bugsee-dotnet-sdk description: Full Bugsee SDK setup for .NET MAUI. Use when asked to add Bugsee to .NET, MAUI, install Bugsee NuGet, or set up bug reporting, crash reporting, and video recording for .NET mobile applications. -sidebar_label: ".NET / MAUI" +sidebar_label: .NET / MAUI sidebar_position: 6 slug: "/ai/agent-skills/sdk/dotnet/SKILL" -license: proprietary +license: MIT category: sdk-setup +generated_from: bugsee-for-ai/skills/bugsee-dotnet-sdk/SKILL.md --- # Bugsee .NET SDK @@ -53,10 +54,12 @@ find . -name "AppDelegate.cs" -o -name "MainApplication.cs" -o -name "MauiProgra Install via NuGet: ```bash -dotnet add package Bugsee +dotnet add package Bugsee --version 6.0.3 ``` -Or in Visual Studio: right-click Dependencies > Manage NuGet Packages > search "Bugsee" > Install. +Or in Visual Studio: right-click Dependencies > Manage NuGet Packages > search "Bugsee" > Install **6.0.3**. + +Current NuGet latest (re-verified 2026-08-25): **Bugsee 6.0.3**. Pin it; `dotnet add package Bugsee` without `--version` is acceptable only after confirming that still resolves to 6.0.3. --- @@ -145,6 +148,16 @@ Build and run on a device. The Bugsee floating button should appear. Tap it to f --- +## Debug Symbols + +Upload the symbol files for the release build so managed and native frames resolve. The .NET MAUI MSBuild target bundles and invokes the [Bugsee CLI](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-cli/SKILL.md); in CI you can run the same binary directly. + +A MAUI app crashing on iOS or Android also needs that platform's native symbols β€” dSYMs or the R8 mapping β€” not just the managed ones. + +Full workflow: [`bugsee-upload-symbols`](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-upload-symbols/SKILL.md) Β· [.NET symbolication](https://docs.bugsee.com/sdk/dotnet/symbolication/). + +--- + ## Documentation Links - [Installation](https://docs.bugsee.com/sdk/dotnet/installation/) diff --git a/docs/ai/agent-skills/sdk/flutter/SKILL.md b/docs/ai/agent-skills/sdk/flutter/SKILL.md index 45c56dc..6b58623 100644 --- a/docs/ai/agent-skills/sdk/flutter/SKILL.md +++ b/docs/ai/agent-skills/sdk/flutter/SKILL.md @@ -1,12 +1,13 @@ --- -title: "Bugsee Flutter SDK" +title: Bugsee Flutter SDK name: bugsee-flutter-sdk description: Full Bugsee SDK setup for Flutter. Use when asked to add Bugsee to Flutter, install bugsee_flutter, or set up bug reporting, crash reporting, and video recording for Flutter applications. -sidebar_label: "Flutter" +sidebar_label: Flutter sidebar_position: 3 slug: "/ai/agent-skills/sdk/flutter/SKILL" -license: proprietary +license: MIT category: sdk-setup +generated_from: bugsee-for-ai/skills/bugsee-flutter-sdk/SKILL.md --- # Bugsee Flutter SDK @@ -19,7 +20,7 @@ Opinionated wizard that scans your Flutter project and guides you through comple - User wants bug reporting, crash reporting, video recording, or network monitoring in Flutter - User mentions `bugsee_flutter`, Bugsee for Dart, or Bugsee Flutter plugin -> **Note:** Always verify against [docs.bugsee.com/sdk/flutter/installation/](https://docs.bugsee.com/sdk/flutter/installation/) before implementing. +> **Note:** Always verify against [docs.bugsee.com/sdk/flutter/installation/](https://docs.bugsee.com/sdk/flutter/installation/) before implementing. Install from **pub.dev** (`bugsee_flutter`). Do not add a git dependency on `github.com/bugsee/flutter-bugsee` β€” that repo is not the current package source. --- @@ -57,9 +58,11 @@ Add to `pubspec.yaml`: ```yaml dependencies: - bugsee_flutter: ^8.0.0 + bugsee_flutter: ^9.0.4 ``` +Current pub.dev latest (re-verified 2026-08-25): **9.0.4**. Docs still show `^8.0.0` β€” pin from the registry, not the installation page. + Then run: ```bash @@ -118,7 +121,7 @@ class MyApp extends StatelessWidget { > Replace `` and `` with tokens from your Bugsee dashboard. It is common to use different app tokens for iOS and Android. **Key points:** -- `HttpOverrides.global = Bugsee.defaultHttpOverrides;` is required to intercept network requests +- `HttpOverrides.global = Bugsee.defaultHttpOverrides;` is required to intercept Dart network requests (`dart:io` `HttpClient`, including `package:http`) β€” there is no default for it. Capture needs **both** this and the `monitorNetwork` launch option (default `true`); setting `monitorNetwork` to `false` disables capture regardless of the overrides ([network](https://docs.bugsee.com/sdk/flutter/network/)) - `Bugsee.launch()` with `appRunCallback` ensures all errors in the app are captured in the proper zone --- @@ -177,6 +180,16 @@ You should see the Bugsee floating button. Tap it to file a test bug report, the --- +## Debug Symbols + +A Flutter release obfuscates Dart symbols, and the platform layers below it are stripped separately. Upload the Dart split debug info **and** the native symbols β€” iOS dSYMs, Android R8 mapping and ELF β€” or half the trace stays raw. + +The Flutter integration downloads and invokes the [Bugsee CLI](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-cli/SKILL.md) for the upload; you can also run it directly from CI. + +Full workflow: [`bugsee-upload-symbols`](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-upload-symbols/SKILL.md) Β· [Flutter symbolication](https://docs.bugsee.com/sdk/flutter/symbolication/). + +--- + ## Documentation Links - [Installation](https://docs.bugsee.com/sdk/flutter/installation/) diff --git a/docs/ai/agent-skills/sdk/ios/SKILL.md b/docs/ai/agent-skills/sdk/ios/SKILL.md index abb5eb3..873f575 100644 --- a/docs/ai/agent-skills/sdk/ios/SKILL.md +++ b/docs/ai/agent-skills/sdk/ios/SKILL.md @@ -1,25 +1,46 @@ --- -title: "Bugsee iOS SDK" +title: Bugsee iOS SDK name: bugsee-ios-sdk -description: Full Bugsee SDK setup for iOS. Use when asked to add Bugsee to iOS, install Bugsee via CocoaPods or SPM, or set up bug reporting, crash reporting, and video recording for iOS applications. -sidebar_label: "iOS" +description: Full Bugsee SDK setup for iOS. Use when asked to add Bugsee to iOS, install Bugsee via SPM, CocoaPods, or Carthage, or set up bug reporting, crash reporting, video recording, APM, or build size analysis for iOS applications. +sidebar_label: iOS sidebar_position: 2 slug: "/ai/agent-skills/sdk/ios/SKILL" -license: proprietary +license: MIT category: sdk-setup +generated_from: bugsee-for-ai/skills/bugsee-ios-sdk/SKILL.md --- # Bugsee iOS SDK -Opinionated wizard that scans your iOS project and guides you through complete Bugsee setup β€” bug reporting with video, crash reporting, network monitoring, and console logs. +Opinionated wizard that scans your iOS project and guides you through complete Bugsee setup β€” bug reporting with video, crash reporting, network monitoring, console logs, APM, and optional build size analysis. + +Current stable pin (re-verified 2026-10-08 against the SPM tags and CocoaPods trunk; matches the [6.x release notes](https://docs.bugsee.com/sdk/ios/release-notes/)): + +- **SPM** tag `6.3.2` at `https://github.com/bugsee/spm` +- **CocoaPods** trunk pod `Bugsee` `6.3.2` +- **Carthage** binary catalog also lists `6.3.2` + +> **Note:** Always verify against [docs.bugsee.com/sdk/ios/installation/](https://docs.bugsee.com/sdk/ios/installation/) before implementing. Prefer registry tags over the release-notes page when they disagree. + +> **7.x is in beta β€” do not install it unless the user explicitly asks.** Latest SPM tag is `7.0.0-beta5` (also beta1–beta4) on `https://github.com/bugsee/spm`; `https://github.com/bugsee/feedback-spm` has matching tags. The [7.x release notes](https://docs.bugsee.com/sdk/ios/v7/release-notes/), [installation](https://docs.bugsee.com/sdk/ios/v7/installation/), and [migration guide](https://docs.bugsee.com/sdk/ios/v7/migration/) now document through **beta5** (checked 2026-10-08). This skill targets **6.x**; for a 7.x beta follow those pages rather than the 6.x code below. Pin both packages with the **Exact Version** rule at the **same** tag (`7.0.0-beta5`) β€” SPM keeps pre-releases out of version ranges, so "Up to Next Major" from 6.3.2 never resolves a 7.x beta. +> +> 7.x is a breaking line. Agent-relevant facts now on docs.bugsee.com: +> - **Minimum is iOS 15 / tvOS 15** (raised in beta2; beta1's iOS 13 / tvOS 13 floor is obsolete). visionOS 1 unchanged. SPM is the only channel (CocoaPods and Carthage retired). +> - Every option constant is renamed into the `BugseeOption*` family (hard-coded strings silently fall back to defaults). `pause`/`resume` and several other methods are removed or renamed. +> - Feedback is a separate package: add `https://github.com/bugsee/feedback-spm` at the same Exact Version as core. Each `BugseeFeedback` release requires that core version exactly. +> - Nine defaults changed. The ninth (beta3): `BugseeOptionCaptureMachExceptions` is **YES** on iOS and visionOS (set `NO` for BSD signal handlers; tvOS always uses BSD). +> - Every `BugseeDelegate` method has a new Swift name ([migration Β§4.6](https://docs.bugsee.com/sdk/ios/v7/migration/)). A 6.x-named Swift implementation compiles but is **never called**. +> - The `BugseeReport` passed to the delegate is a live handle β€” mutations are what gets uploaded (`type` is read-only; no public initializer; do not keep it past the callback). +> - `addSecureRectangle:` drops touches as well as pixels. Multi-window recording (beta4) records every window on screen; convert rectangles to screen coordinates. +> - `log:level:enforceFiltering:` is renamed `log:level:requiresFiltering:`. + +--- ## Invoke This Skill When - User asks to "add Bugsee to iOS" or "set up Bugsee" in an iOS/iPadOS app -- User wants bug reporting, crash reporting, video recording, or network monitoring in iOS -- User mentions Bugsee CocoaPods, Bugsee SPM, or Bugsee for Swift/Objective-C - -> **Note:** Always verify against [docs.bugsee.com/sdk/ios/installation/](https://docs.bugsee.com/sdk/ios/installation/) before implementing. +- User wants bug reporting, crash reporting, video recording, network monitoring, APM, or build size analysis in iOS +- User mentions Bugsee CocoaPods, Bugsee SPM, Bugsee Carthage, or Bugsee for Swift/Objective-C --- @@ -50,9 +71,9 @@ grep -r "@main" --include="*.swift" 2>/dev/null | head -3 | Question | Impact | |----------|--------| -| `Podfile` exists? | Use CocoaPods installation | -| `Package.swift` exists or SPM? | Use Swift Package Manager | +| `Package.swift` exists or SPM? | Prefer Swift Package Manager (recommended going forward) | | `Cartfile` exists? | Use Carthage installation | +| `Podfile` exists? | CocoaPods still works for existing projects; see the CocoaPods note below | | No dependency manager? | Use manual framework installation | | Swift files found? | Show Swift init code | | Objective-C files found? | Show Objective-C init code | @@ -64,35 +85,21 @@ grep -r "@main" --include="*.swift" 2>/dev/null | head -3 ## Phase 2: Install -Choose one method based on detected dependency manager: - -### CocoaPods - -Add to `Podfile`: - -```ruby -pod 'Bugsee' -``` - -Then run: - -```bash -pod install -``` +Choose one method based on the detected dependency manager. **Prefer SPM or Carthage for new installs.** CocoaPods trunk is scheduled to become read-only on **December 2, 2026** (test window November 1–7, 2026 per [the CocoaPods blog](https://blog.cocoapods.org/CocoaPods-Specs-Repo/)); existing Pod installs and the CDN continue to work. Keep the CocoaPods path for existing `Podfile` projects (6.3.2 is already on trunk). -### Swift Package Manager +### Swift Package Manager (recommended) Add the package in Xcode: 1. File > Add Package Dependencies 2. Enter URL: `https://github.com/bugsee/spm` -3. Select version rule and add to target +3. Select version **6.3.2** (latest tag) and add it to the app target ### Carthage Add to `Cartfile`: ``` -binary "https://docs.bugsee.com/sdk/ios/Bugsee.json" +binary "https://download.bugsee.com/sdk/ios/dynamic/Bugsee.json" ``` Then run: @@ -103,6 +110,21 @@ carthage update --use-xcframeworks Drag `Bugsee.xcframework` from `Carthage/Build` into your target's "Frameworks, Libraries, and Embedded Content". +### CocoaPods (existing Podfile projects) + +CocoaPods trunk is scheduled to become read-only on **December 2, 2026** (test window November 1–7, 2026). Existing Pod installs and the CDN continue to work; only new Podspec publishes stop. Prefer SPM or Carthage for new integrations. If the project already uses CocoaPods, add to `Podfile`: + +```ruby +pod 'Bugsee', '6.3.2' +``` + +Then run: + +```bash +pod install +pod update Bugsee # install alone does not guarantee the latest trunk version +``` + ### Manual 1. Download from [https://download.bugsee.com/sdk/ios/dynamic/Bugsee-stable.xcframework.zip](https://download.bugsee.com/sdk/ios/dynamic/Bugsee-stable.xcframework.zip) @@ -161,6 +183,9 @@ let options = BugseeOptions() options.shakeToReport = true options.reportPrioritySelector = true options.maxRecordingTime = 60 +options.captureVideoAdaptive = true // 6.3.0 β€” lower FPS on idle UI +options.performanceMonitoring = true // 6.2.0 β€” APM (default YES) +options.sanitizeNetworkData = true // 6.1.3 β€” PII redaction (default YES) Bugsee.launch(token: "", options: options) ``` @@ -171,9 +196,14 @@ BugseeOptions *options = [[BugseeOptions alloc] init]; options.shakeToReport = YES; options.reportPrioritySelector = YES; options.maxRecordingTime = 60; +options.captureVideoAdaptive = YES; +options.performanceMonitoring = YES; +options.sanitizeNetworkData = YES; [Bugsee launchWithToken:@"" options:options]; ``` +Dictionary-key equivalents (same names as on the [configuration](https://docs.bugsee.com/sdk/ios/configuration/) page): `BugseeCaptureVideoAdaptiveKey` (`"CaptureVideoAdaptive"`), `BugseePerformanceMonitoringKey` (`performanceMonitoring`), `BugseeSanitizeNetworkDataKey` (`sanitizeNetworkData`). The configuration page may lag the 6.3.2 headers; the keys above are in the current SDK. + Common options: | Option | Default | Description | @@ -181,14 +211,78 @@ Common options: | `videoEnabled` | `true` | Enable video recording | | `crashReport` | `true` | Catch and report crashes | | `monitorNetwork` | `true` | Capture network traffic | +| `sanitizeNetworkData` | `true` | Auto-redact known PII keys from captured network events (6.1.3). Applies only when no custom network filter is set. | | `captureLogs` | `true` | Capture console logs | +| `captureOSLogs` | `false` | **No effect since 6.3.2** β€” `os_log` / `Logger` capture was permanently disabled (it polled the log store all session). Still compiles; do not enable it expecting output. Use `Bugsee.log(...)` or `NSLog` for logs you want captured. | | `maxRecordingTime` | `60` | Max recording duration (seconds) | | `shakeToReport` | `false` | Shake device to trigger report | | `screenshotEnabled` | `true` | Attach screenshot to report | | `wifiOnlyUpload` | `false` | Upload only on WiFi | +| `captureVideoAdaptive` | `false` | Opt-in adaptive screen capture (6.3.0): ~1 fps on a static screen, ramps to `maxFramerate` on visual activity | +| `performanceMonitoring` | `true` | APM master switch (6.2.0). When `false`, `startTransaction` / `startSpan` return a shared no-op | Full options: [docs.bugsee.com/sdk/ios/configuration/](https://docs.bugsee.com/sdk/ios/configuration/) +### APM (`startTransaction` / `startSpan`) β€” 6.2.0+ + +Auto-instruments NSURLSession HTTP, NSData file I/O, NSFileManager operations, UIViewController lifecycle, and app startup. Transactions are attached to every report. SwiftUI auto-instrumentation is not in 6.3.2 yet. + +**Swift:** + +```swift +let tx = Bugsee.startTransaction(name: "Checkout", operation: "ui.checkout") +let span = Bugsee.startSpan(operation: "db.query", description: "SELECT cart") +// ... work ... +span.finish() +tx.finish() // no-arg finish implies SpanStatus.ok +``` + +**Objective-C:** + +```objectivec +id tx = [Bugsee startTransactionWithName:@"Checkout" operation:@"ui.checkout"]; +id span = [Bugsee startSpanWithOperation:@"db.query" description:@"SELECT cart"]; +[span finish]; +[tx finishWithStatus:BGSSpanStatusOK]; +``` + +When `performanceMonitoring` is `NO`, both APIs return a shared no-op singleton β€” no null checks needed. `startSpan` parents to the current active span on the calling thread (pthread TLS; it does not auto-propagate across `dispatch_async`). + +### BugseeAgent size analysis β€” 6.1.5+ + +The same `BugseeAgent` post-action that uploads dSYMs also registers a build record (version, configuration, VCS context, timings, Mach-O `LC_UUID`). Size analysis is opt-in. + +1. Add a Run Script **Archive** post-action (Product β†’ Scheme β†’ Edit Scheme β†’ Archive β†’ Post-actions). Set **Provide build settings from** to the app target. +2. Script body (CocoaPods / manual β€” locates `BugseeAgent` in the project): + + ```bash + SCRIPT_SRC=$(find "$PROJECT_DIR" -name 'BugseeAgent' | head -1) + if [ ! "$SCRIPT_SRC" ]; then + echo "Error: BugseeAgent not found" + exit 1 + fi + python3 "$SCRIPT_SRC" >> /tmp/BugseeAgent.txt + ``` + + For **SPM**, replace the `find` line with: + + ```bash + SCRIPT_SRC="$BUILD_DIR/../SourcePackages/checkouts/spm/Tools/BugseeAgent" + ``` + +3. `BUGSEE_BUILD_INFO_ENABLED` is **ON by default** β€” do not set it. To also upload the IPA for download/install size, per-category breakdown, and per-file diffs, add scheme Environment Variables: + + ```text + BUGSEE_SIZE_ANALYSIS_ENABLED=1 + # optional: + # BUGSEE_CHUNKED_UPLOAD=1 + # BUGSEE_SIZE_CHECK_ENABLED=1 + # BUGSEE_SIZE_CHECK_WARNING_PCT=5.0 + # BUGSEE_SIZE_CHECK_FAIL_PCT=10.0 + ``` + +Full env-var reference: [build size analysis](https://docs.bugsee.com/sdk/ios/build-size-analysis/) Β· [symbolication](https://docs.bugsee.com/sdk/ios/symbolication/) + --- ## Verification @@ -199,6 +293,21 @@ Check the Bugsee dashboard for the incoming report. --- +## Debug Symbols + +A Release build strips symbols, so crashes arrive as raw addresses until dSYMs are uploaded. Confirm `DEBUG_INFORMATION_FORMAT = dwarf-with-dsym` for the Release configuration first β€” without it there are no dSYMs to upload at all. + +Two shapes, both driven by the [Bugsee CLI](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-cli/SKILL.md): + +- **Scheme post-action** β€” the SDK's `BugseeAgent` script runs `bugsee-cli xcode post-action` from Archive β†’ Post-actions. Uploads dSYMs *and* registers the build (build info, dependencies, timings, optional size analysis). Gated to Release + Archive by default. +- **Run Script build phase** β€” `bugsee-cli xcode upload-dsyms` (CLI 0.7.7+) uploads dSYMs alone, with no build registration, so it is safe on every build. A genuine failure fails the build on purpose; `--no-fail --no-background` is the usual CI combination. + +> **Xcode 15+:** `ENABLE_USER_SCRIPT_SANDBOXING` defaults to `YES` and blocks a build phase from reading the dSYM folder. Set it to `NO` on the target, or declare the folder in the phase's input file lists. + +Full workflow, including manual upload of App Store Connect dSYMs: [`bugsee-upload-symbols`](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-upload-symbols/SKILL.md). + +--- + ## Documentation Links - [Installation](https://docs.bugsee.com/sdk/ios/installation/) @@ -208,5 +317,7 @@ Check the Bugsee dashboard for the incoming report. - [Console logs](https://docs.bugsee.com/sdk/ios/logs/) - [Privacy](https://docs.bugsee.com/sdk/ios/privacy/overview/) - [Crash symbolication](https://docs.bugsee.com/sdk/ios/symbolication/) +- [Build size analysis](https://docs.bugsee.com/sdk/ios/build-size-analysis/) - [Manual invocation](https://docs.bugsee.com/sdk/ios/manual/) - [Release notes](https://docs.bugsee.com/sdk/ios/release-notes/) +- [7.x beta: installation](https://docs.bugsee.com/sdk/ios/v7/installation/) Β· [migration from 6.x](https://docs.bugsee.com/sdk/ios/v7/migration/) Β· [release notes](https://docs.bugsee.com/sdk/ios/v7/release-notes/) diff --git a/docs/ai/agent-skills/sdk/kmp/SKILL.md b/docs/ai/agent-skills/sdk/kmp/SKILL.md index 267ef27..7ac9666 100644 --- a/docs/ai/agent-skills/sdk/kmp/SKILL.md +++ b/docs/ai/agent-skills/sdk/kmp/SKILL.md @@ -1,12 +1,13 @@ --- -title: "Bugsee KMP SDK" +title: Bugsee KMP SDK name: bugsee-kmp-sdk description: Full Bugsee SDK setup for Kotlin Multiplatform. Use when asked to add Bugsee to KMP, install bugsee-kotlin-multiplatform, or set up bug reporting, crash reporting, and video recording for KMP applications. -sidebar_label: "KMP" +sidebar_label: KMP sidebar_position: 9 slug: "/ai/agent-skills/sdk/kmp/SKILL" -license: proprietary +license: MIT category: sdk-setup +generated_from: bugsee-for-ai/skills/bugsee-kmp-sdk/SKILL.md --- # Bugsee KMP SDK @@ -74,17 +75,19 @@ kotlin { cocoapods { // ... your existing cocoapods configuration - pod("Bugsee") + pod("Bugsee") // native iOS SDK; trunk latest 6.3.2. CocoaPods trunk becomes read-only on December 2, 2026 β€” see the iOS skill for SPM/Carthage if you are not using the Kotlin CocoaPods plugin. } sourceSets { commonMain.dependencies { - implementation("com.bugsee:bugsee-kotlin-multiplatform:0.1.1") + implementation("com.bugsee:bugsee-kotlin-multiplatform:0.1.2") } } } ``` +Current Maven latest (re-verified 2026-09-24): **0.1.2**. Pin that version β€” docs still show `+`, which the KMP installation page itself warns against (`Pin your dependency to a specific version rather than using a floating range`). + > **Note:** The CocoaPods integration approach can't be used together with the `embedAndSignAppleFrameworkForXcode` mechanism used for direct integration. See [Kotlin CocoaPods overview](https://kotlinlang.org/docs/multiplatform/multiplatform-cocoapods-overview.html#set-up-an-environment-to-work-with-cocoapods). Then sync Gradle: @@ -138,8 +141,9 @@ Add `Bugsee.launch()` in your `ComposeUIViewController` entry point: import androidx.compose.ui.window.ComposeUIViewController import com.bugsee.kmp.Bugsee import com.bugsee.kmp.BugseeLaunchOptions +import platform.UIKit.UIViewController -fun MainViewController() = ComposeUIViewController { +fun MainViewController(): UIViewController { val options = BugseeLaunchOptions() options.monitorNetwork = true options.captureLogs = true @@ -148,7 +152,9 @@ fun MainViewController() = ComposeUIViewController { options.shakeToReport = true Bugsee.launch("", options) - App() + return ComposeUIViewController { + App() + } } ``` @@ -194,17 +200,19 @@ Full options: [docs.bugsee.com/sdk/kmp/configuration/](https://docs.bugsee.com/s ## Phase 5: Debug symbols (Production builds) -For readable stack traces from release builds, upload platform debug symbols. There is no KMP-specific upload tool β€” follow the native workflows on each platform. +For readable stack traces from release builds, upload platform debug symbols. There is no KMP-specific upload tool β€” follow the native workflows on each platform. Both run on the [Bugsee CLI](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-cli/SKILL.md) underneath, so a CI job without Gradle or Xcode can invoke it directly. ### Android -In a typical KMP/Compose Multiplatform project, wire the Bugsee Gradle plugin into `composeApp/build.gradle.kts`: +In a typical KMP/Compose Multiplatform project, wire the Bugsee Gradle plugin into `composeApp/build.gradle.kts`. **Match the plugin line to the native Android SDK the KMP release wraps** β€” lines are not cross-compatible ([requirements](https://docs.bugsee.com/sdk/android/gradle-plugin/requirements/)): plugin **3.x ↔ SDK 6.x**, plugin **4.x ↔ SDK 7.x**. + +KMP **0.1.2** wraps native Android SDK **6.0.4** (its Maven POM's `com.bugsee:bugsee-android` dependency; check the [KMP release notes](https://docs.bugsee.com/sdk/kmp/release-notes/) for later releases), so pin plugin **3.6** β€” the latest 3.x β€” and use the boolean `ndk(true)`. **Do not** reach for plugin 4.x here: it expects the 7.x module layout, auto-pulls `com.bugsee:bugsee-android` on the 7.x range, and its nested `ndk { enabled.set(true) }` block does not exist on 3.x (using it there fails with `Type mismatch: inferred type is () -> Unit but Boolean was expected`). Once a KMP release wraps SDK 7.x, switch to plugin 4.0.7 (never 4.0.6) and the nested block β€” see [`bugsee-android-sdk`](https://docs.bugsee.com/ai/agent-skills/sdk/android/v7/SKILL.md). ```kotlin // gradle/libs.versions.toml // // [versions] -// bugseeGradle = "x.y.z" // plugin line paired with the native SDK this KMP release wraps β€” see release notes +// bugseeGradle = "3.6" // plugin line paired with the native SDK this KMP release wraps (6.x -> 3.x) // // [plugins] // bugsee-gradle-plugin = { id = "com.bugsee.android.gradle", version.ref = "bugseeGradle" } @@ -229,8 +237,6 @@ android { } ``` -> **Note:** The Gradle plugin line must match the native Android SDK this KMP release wraps. Check the [KMP release notes](https://docs.bugsee.com/sdk/kmp/release-notes/) for the wrapped SDK version, then pick the paired plugin line from [Gradle plugin β€” Requirements & compatibility](https://docs.bugsee.com/sdk/android/gradle-plugin/requirements/). The NDK syntax differs by line: plugin 4.x takes a nested block (`ndk { enabled.set(true) }`), earlier lines take the boolean `ndk(true)` shown above. Using the nested block on a line that expects the boolean fails to compile with `Type mismatch: inferred type is () -> Unit but Boolean was expected`. - The plugin uploads the ProGuard/R8 `mapping.txt` automatically at build time. ### iOS @@ -241,95 +247,7 @@ Set `DEBUG_INFORMATION_FORMAT` to `dwarf-with-dsym` for the configurations you w Full instructions and the BugseeAgent script: [docs.bugsee.com/sdk/kmp/debug-symbols/](https://docs.bugsee.com/sdk/kmp/debug-symbols/). ---- - -## Verification - -Build and run the app on both an Android device/emulator and an iOS device/simulator, then work through the steps below. - -### 1. Confirm the SDK actually started - -```kotlin -import com.bugsee.kmp.Bugsee - -// Anywhere after launch(), from commonMain -println("Bugsee launched: ${Bugsee.isLaunched()}") -``` - -`Bugsee.isLaunched()` is backed by the native SDKs on both targets, so `false` means `launch()` bailed out rather than that the check is unsupported. - -### 2. File a test report - -The default trigger gesture differs per platform β€” `BugseeLaunchOptions` defaults `shakeToReport` to `true` on Android and `screenshotToReport` to `true` on iOS: - -- **Android** β€” shake the device -- **iOS** β€” take a screenshot - -Or trigger the dialog from shared code, which works on both: - -```kotlin -import com.bugsee.kmp.Bugsee -import com.bugsee.kmp.BugseeSeverity - -Bugsee.showReportDialog() - -// Or pre-filled -Bugsee.showReportDialog("Smoke test", "Verifying Bugsee KMP setup", BugseeSeverity.Medium) -``` - -Valid `BugseeSeverity` values are `VeryLow`, `Medium`, `High`, `Critical`, and `Blocker`. - -### 3. Verify exception and crash capture - -A handled exception is the safest check β€” it does not terminate the app: - -```kotlin -try { - (null as String?)!!.length -} catch (ex: Exception) { - Bugsee.logException(ex) -} -``` - -For an uncaught crash, be aware of a Compose Multiplatform gotcha: on Android a throwable raised synchronously inside a `Modifier.clickable` lambda is absorbed by the pointer-input coroutine and never reaches `Thread.UncaughtExceptionHandler`, so Bugsee cannot capture it. Throw from a background thread instead β€” this works uniformly on both targets: - -```kotlin -// commonMain -expect fun runOnBackgroundThread(block: () -> Unit) - -// androidMain β€” the throwable reaches AndroidRuntime and Bugsee -actual fun runOnBackgroundThread(block: () -> Unit) { - Thread { block() }.start() -} - -// iosMain β€” the throwable goes through Kotlin/Native's unhandled-exception hook, -// which Bugsee installs on successful launch when crashReport is enabled -@OptIn(ExperimentalForeignApi::class) -actual fun runOnBackgroundThread(block: () -> Unit) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT.toLong(), 0u)) { - block() - } -} - -// Test: remove after verifying -runOnBackgroundThread { throw RuntimeException("Bugsee KMP smoke test") } -``` - -Relaunch the app afterwards β€” crash reports are uploaded on the next start. - -### 4. If nothing arrives - -**Android** β€” check logcat for the KMP layer's own diagnostics: - -```bash -adb logcat -s BugseeInternal -``` - -`Bugsee KMP: cannot launch() β€” applicationContext is not gathered` means `launch()` ran before the SDK's internal `ContentProvider` captured the application context. Call `launch()` from `Application.onCreate()` (not `attachBaseContext()`), and confirm `android:name` on the `` tag actually points at your `Application` subclass. - -**iOS** β€” the KMP layer logs through `NSLog` with a `DEBUG: [BugseeInternal] …` / `ERROR: [BugseeInternal] …` prefix. Filter the Xcode console for `BugseeInternal`. - -Finally, check the Bugsee dashboard for the incoming reports. +If editing `.xcscheme` XML is awkward β€” a generated `iosApp` project, or a CI-only setup β€” `bugsee-cli xcode upload-dsyms` (CLI 0.7.7+) does the dSYM upload from an ordinary **Run Script build phase** instead, with no build registration. See [`bugsee-upload-symbols`](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-upload-symbols/SKILL.md) for both shapes and their failure policies. --- diff --git a/docs/ai/agent-skills/sdk/react-native/SKILL.md b/docs/ai/agent-skills/sdk/react-native/SKILL.md index 8bf7baf..6898bcf 100644 --- a/docs/ai/agent-skills/sdk/react-native/SKILL.md +++ b/docs/ai/agent-skills/sdk/react-native/SKILL.md @@ -1,12 +1,13 @@ --- -title: "Bugsee React Native SDK" +title: Bugsee React Native SDK name: bugsee-react-native-sdk description: Full Bugsee SDK setup for React Native. Use when asked to add Bugsee to React Native, install react-native-bugsee, or set up bug reporting, crash reporting, and video recording for React Native applications. -sidebar_label: "React Native" +sidebar_label: React Native sidebar_position: 4 slug: "/ai/agent-skills/sdk/react-native/SKILL" -license: proprietary +license: MIT category: sdk-setup +generated_from: bugsee-for-ai/skills/bugsee-react-native-sdk/SKILL.md --- # Bugsee React Native SDK @@ -54,9 +55,11 @@ ls App.js App.tsx index.js 2>/dev/null ### 1. Install the npm module ```bash -npm install --save react-native-bugsee +npm install --save react-native-bugsee@6.0.5 ``` +Current npm latest (re-verified 2026-08-25): **6.0.5**. Pin the version; an unpinned `npm install` can silently resolve an older cache. + ### 2. Prepare iOS project Run CocoaPods: @@ -78,6 +81,7 @@ After installing the module, perform a Gradle Sync. No additional manual configu Add Bugsee launch to your main `App.js` or `App.tsx`: ```javascript +import React from 'react'; import Bugsee from 'react-native-bugsee'; import { Platform } from 'react-native'; @@ -108,8 +112,8 @@ export default class App extends React.Component { For functional components: ```javascript -import Bugsee from 'react-native-bugsee'; import { useEffect } from 'react'; +import Bugsee from 'react-native-bugsee'; import { Platform } from 'react-native'; function App() { @@ -162,6 +166,38 @@ You should see the Bugsee floating button. Tap it to file a test bug report, the --- +## Debug Symbols + +A React Native crash has **two layers**, and each needs its own symbols. Uploading only one leaves half the trace raw. + +**JavaScript β€” source maps.** The `bugsee-sourcemaps` npm tool is the documented React Native path and still the safe default: + +It ships as a `react-native-bugsee` devDependency β€” **do not install it globally unpinned**: + +```bash +npx bugsee-sourcemaps make -t -p ios -v 1.2.3 ./ +``` + +See [React Native crashes](https://docs.bugsee.com/sdk/react_native/crashes/) and [docs.bugsee.com/tools/sourcemaps](https://docs.bugsee.com/tools/sourcemaps/). + +The [Bugsee CLI](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-cli/SKILL.md) can do it instead β€” one binary for JS *and* native β€” but mind the file extension: + +```bash +npm i -D @bugsee/cli@0.8.1 +# bundle with a .js name: --bundle-output ios/main.js --sourcemap-output ios/main.js.map +npx bugsee-cli sourcemaps inject ios/main.js +npx bugsee-cli debug-files upload ios/main.js.map --type sourcemaps \ + --version 1.4.0 --build 1400 +``` + +> **`inject` only rewrites `.js`, `.cjs`, and `.mjs` files.** React Native's default `main.jsbundle` output is **skipped silently** β€” it reports `js_injected=0` and exits 0, and the upload then fails because the map carries no debug ID. Either emit the bundle with a `.js` name, or stay on `bugsee-sourcemaps`. + +**Native.** iOS needs dSYMs β€” `bugsee-cli xcode upload-dsyms` from a Run Script build phase (CLI 0.7.7+) is the shape a config plugin can generate via `withXcodeProject`. Android needs the R8/ProGuard mapping, which the Bugsee Android Gradle plugin uploads automatically. + +Full workflow: [`bugsee-upload-symbols`](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-upload-symbols/SKILL.md). + +--- + ## Documentation Links - [Installation](https://docs.bugsee.com/sdk/react_native/installation/) diff --git a/docs/ai/agent-skills/sdk/unity/SKILL.md b/docs/ai/agent-skills/sdk/unity/SKILL.md index 1d0e28d..918a397 100644 --- a/docs/ai/agent-skills/sdk/unity/SKILL.md +++ b/docs/ai/agent-skills/sdk/unity/SKILL.md @@ -1,12 +1,13 @@ --- -title: "Bugsee Unity SDK" +title: Bugsee Unity SDK name: bugsee-unity-sdk description: Full Bugsee SDK setup for Unity. Use when asked to add Bugsee to Unity, install Bugsee Unity package, or set up bug reporting, crash reporting, and video recording for Unity games. -sidebar_label: "Unity" +sidebar_label: Unity sidebar_position: 5 slug: "/ai/agent-skills/sdk/unity/SKILL" -license: proprietary +license: MIT category: sdk-setup +generated_from: bugsee-for-ai/skills/bugsee-unity-sdk/SKILL.md --- # Bugsee Unity SDK @@ -49,7 +50,7 @@ grep -r "AndroidManifest" Assets/Plugins 2>/dev/null | head -3 ## Phase 2: Install -1. Download the latest [Bugsee.unitypackage](https://download.bugsee.com/sdk/unity/BugseeUnity-stable.unitypackage) (or see [all versions](https://docs.bugsee.com/sdk/unity/versions/)) +1. Download the latest [Bugsee.unitypackage](https://download.bugsee.com/sdk/unity/BugseeUnity-stable.unitypackage) (or see [all versions](https://docs.bugsee.com/sdk/unity/versions/)). Source repo: [github.com/bugsee/bugsee-unity](https://github.com/bugsee/bugsee-unity). 2. Import the package in Unity: Assets > Import Package > Custom Package @@ -139,6 +140,23 @@ Build and run on a device. The Bugsee floating button should appear. Tap it to f --- +## Debug Symbols + +An IL2CPP build needs the line-number mapping **in addition to** the platform's native symbols (iOS dSYMs, Android ELF). Upload it with the [Bugsee CLI](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-cli/SKILL.md): + +```bash +bugsee-cli debug-files upload path/to/Symbols/LineNumberMappings.json \ + --type il2cpp-linemap \ + --version 1.2.3 --build 45 \ + --uuid , +``` + +The mapping is keyed by the IL2CPP module UUID(s) (`libil2cpp` / `UnityFramework`) β€” comma-separate them, or repeat `--uuid`, for a multi-ABI Android build. Sibling `MethodMap.tsv` / `il2cppFileRoot.txt` are picked up automatically when they sit next to the JSON. CLI **0.8.0+** validates the JSON before packing; a truncated or corrupt file exits **11** and uploads nothing. + +Full workflow: [`bugsee-upload-symbols`](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-upload-symbols/SKILL.md) Β· [Unity crashes](https://docs.bugsee.com/sdk/unity/crashes/). + +--- + ## Documentation Links - [Installation](https://docs.bugsee.com/sdk/unity/installation/) diff --git a/docs/ai/agent-skills/sdk/xamarin/SKILL.md b/docs/ai/agent-skills/sdk/xamarin/SKILL.md index 6d9079a..db3e6a5 100644 --- a/docs/ai/agent-skills/sdk/xamarin/SKILL.md +++ b/docs/ai/agent-skills/sdk/xamarin/SKILL.md @@ -1,22 +1,17 @@ --- -title: "Bugsee Xamarin SDK" +title: Bugsee Xamarin SDK name: bugsee-xamarin-sdk -description: Full Bugsee SDK setup for Xamarin. DEPRECATED β€” Microsoft ended Xamarin support on May 1, 2024 and this SDK is no longer actively maintained; prefer the Bugsee .NET SDK for new projects. Use when asked to add Bugsee to Xamarin, install Bugsee NuGet for Xamarin, or set up bug reporting, crash reporting, and video recording for existing Xamarin applications. -sidebar_label: "Xamarin" +description: Full Bugsee SDK setup for Xamarin. Use when asked to add Bugsee to Xamarin, install Bugsee NuGet for Xamarin, or set up bug reporting, crash reporting, and video recording for Xamarin applications. +sidebar_label: Xamarin sidebar_position: 7 slug: "/ai/agent-skills/sdk/xamarin/SKILL" -license: proprietary +license: MIT category: sdk-setup +generated_from: bugsee-for-ai/skills/bugsee-xamarin-sdk/SKILL.md --- # Bugsee Xamarin SDK -> **Deprecated β€” tell the user before proceeding.** -> Microsoft ended support for Xamarin on May 1, 2024, and the Bugsee Xamarin SDK is no longer -> actively maintained. For a **new** project, use the [Bugsee .NET SDK](/ai/agent-skills/sdk/dotnet/SKILL) -> instead, which supports .NET MAUI and modern .NET workloads. Only continue with this skill when -> the user is working in an existing Xamarin codebase and has confirmed they want to stay on it. - Opinionated wizard that guides you through complete Bugsee setup in Xamarin β€” bug reporting with video, crash reporting, network monitoring, and console logs for iOS, Android, and Xamarin.Forms. ## Invoke This Skill When @@ -66,9 +61,11 @@ In Visual Studio: right-click project > Add > Add NuGet Packages > search "Bugse Or via CLI: ```bash -nuget install Bugsee +nuget install Bugsee -Version 6.0.3 ``` +Current NuGet latest (re-verified 2026-08-25): **Bugsee 6.0.3** (same package as .NET / MAUI). + > Install the Bugsee package in each platform-specific project (iOS and Android), not the shared/PCL project. --- @@ -146,6 +143,16 @@ Build and run on a device. The Bugsee floating button should appear. Tap it to f --- +## Debug Symbols + +Upload the symbol files for the release build so managed and native frames resolve β€” and the platform's native symbols (iOS dSYMs, Android R8 mapping) alongside them, or the native half of a trace stays raw. + +The [Bugsee CLI](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-cli/SKILL.md) handles every format from a CI script. + +Full workflow: [`bugsee-upload-symbols`](https://github.com/bugsee/bugsee-for-ai/blob/main/skills/bugsee-upload-symbols/SKILL.md) Β· [Xamarin symbolication](https://docs.bugsee.com/sdk/xamarin/symbolication/). + +--- + ## Documentation Links - [Installation](https://docs.bugsee.com/sdk/xamarin/installation/) diff --git a/package.json b/package.json index fc3a91f..4cf0181 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,9 @@ "scripts": { "docusaurus": "docusaurus", "sync-skills": "node scripts/sync-skills.mjs", + "mirror-skills": "node scripts/mirror-skills.mjs", + "check-skills": "node scripts/mirror-skills.mjs --check", + "test:mirror": "node --test scripts/mirror-skills.test.mjs", "prestart": "node scripts/sync-skills.mjs", "start": "docusaurus start --port 8000", "prebuild": "node scripts/sync-skills.mjs", diff --git a/scripts/mirror-skills.mjs b/scripts/mirror-skills.mjs new file mode 100644 index 0000000..eff2744 --- /dev/null +++ b/scripts/mirror-skills.mjs @@ -0,0 +1,198 @@ +#!/usr/bin/env node + +/** + * Mirrors the SDK-setup skills from bugsee/bugsee-for-ai into + * docs/ai/agent-skills/sdk/**, so that bugsee-for-ai is the only place a skill + * is edited and the copies served at docs.bugsee.com/ai/agent-skills/... can + * never drift from it. + * + * node scripts/mirror-skills.mjs regenerate from the pinned commit + * node scripts/mirror-skills.mjs --update move the pin to bugsee-for-ai main, regenerate + * node scripts/mirror-skills.mjs --check fail if any generated file differs from a + * regeneration at the pinned commit (hand edits) + * --source use a local bugsee-for-ai checkout instead of + * fetching (never touches the pin; for testing) + * + * Inputs: scripts/skills-map.json which plugin skill feeds which docs path + * scripts/skills-source.json the bugsee-for-ai commit the copies were built from + * Output: docs/ai/agent-skills//SKILL.md (each carries `generated_from` in its frontmatter) + * + * Files listed under "docsOwned" in the map are not generated and are left alone. + * The existing scripts/sync-skills.mjs then copies the result to static/ for `curl`. + */ + +import { execFileSync } from 'node:child_process'; +import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { dirname, join } from 'node:path'; +import { fileURLToPath, pathToFileURL } from 'node:url'; + +const SCRIPTS = dirname(fileURLToPath(import.meta.url)); +const ROOT = join(SCRIPTS, '..'); +const OUT_ROOT = join(ROOT, 'docs', 'ai', 'agent-skills'); +const MAP_PATH = join(SCRIPTS, 'skills-map.json'); +const PIN_PATH = join(SCRIPTS, 'skills-source.json'); + +/** Frontmatter keys carried over from the plugin skill. Plugin-only keys (`parent`, + * `disable-model-invocation`, `allowed-tools`) are dropped on purpose: the docs copies are + * fetched by hand, and must not pre-approve tools on someone's machine. */ +const KEEP_FROM_SOURCE = ['name', 'description', 'license', 'category']; + +/** Parse a SKILL.md into { fm, body }. Only single-line `key: value` frontmatter is supported; + * anything else throws, so a new frontmatter shape fails loudly instead of being mangled. */ +export function parseSkill(text) { + const m = text.match(/^---\n([\s\S]*?)\n---\n/); + if (!m) throw new Error('SKILL.md has no frontmatter'); + const fm = {}; + for (const line of m[1].split('\n')) { + if (!line.trim()) continue; + if (/^\s/.test(line)) throw new Error(`multi-line frontmatter value is not supported: "${line.trim().slice(0, 60)}"`); + const i = line.indexOf(':'); + if (i === -1) throw new Error(`unparseable frontmatter line: "${line.slice(0, 60)}"`); + fm[line.slice(0, i).trim()] = line.slice(i + 1).trim(); + } + return { fm, body: text.slice(m[0].length) }; +} + +/** YAML-safe scalar: plain when that is unambiguous, otherwise a JSON (= YAML double-quoted) string. */ +export function yamlScalar(v) { + const unwrapped = v.replace(/^"(.*)"$/s, '$1'); + const risky = /(^[-?:,\[\]{}#&*!|>'"%@`])|(: )|( #)|(\s$)/.test(unwrapped) || unwrapped === ''; + return risky ? JSON.stringify(unwrapped) : unwrapped; +} + +/** + * Turn one plugin SKILL.md into its docs copy. + * `mirrored` maps plugin skill name -> docs dest, so links between mirrored skills stay on the site. + */ +export function transformSkill(sourceText, entry, mirrored, cfg) { + const { fm, body } = parseSkill(sourceText); + for (const k of KEEP_FROM_SOURCE) if (!fm[k]) throw new Error(`${entry.plugin}: frontmatter is missing "${k}"`); + if (fm.name !== entry.plugin) throw new Error(`${entry.plugin}: frontmatter name is "${fm.name}"`); + + // The first body line is the plugin's navigation breadcrumb; it points at files that only + // exist inside the plugin repo. + let out = body.replace(/^\n*> \[All Skills\]\([^\n]*\n\n?/, ''); + + const docsBase = cfg.source.docsBase; + out = out.replace(/\]\(\.\.\/(bugsee-[a-z0-9-]+)\/SKILL\.md(#[^)]*)?\)/g, (_, name, anchor = '') => { + const dest = mirrored.get(name); + return dest + ? `](${docsBase}/ai/agent-skills/${dest}/SKILL.md${anchor})` + : `](${cfg.source.blobBase}/skills/${name}/SKILL.md${anchor})`; + }); + out = out.replace(/\]\(\.\.\/\.\.\/SKILL_TREE\.md(#[^)]*)?\)/g, (_, anchor = '') => `](${cfg.source.blobBase}/SKILL_TREE.md${anchor})`); + + const left = out.match(/\]\(\.{1,2}\/[^)]*\)/); + if (left) throw new Error(`${entry.plugin}: unhandled relative link ${left[0]} β€” extend transformSkill()`); + + const lines = [ + '---', + `title: ${yamlScalar(entry.title)}`, + `name: ${yamlScalar(fm.name)}`, + `description: ${yamlScalar(fm.description)}`, + `sidebar_label: ${yamlScalar(entry.label)}`, + `sidebar_position: ${entry.position}`, + `slug: "/ai/agent-skills/${entry.dest}/SKILL"`, + `license: ${yamlScalar(fm.license)}`, + `category: ${yamlScalar(fm.category)}`, + `generated_from: bugsee-for-ai/skills/${entry.plugin}/SKILL.md`, + '---', + '', + '', + ]; + // Exactly one blank line between the frontmatter and the body, whether or not a breadcrumb was stripped. + return lines.join('\n') + out.replace(/^\n+/, ''); +} + +/** Build every generated file as { absolutePath -> content } from a bugsee-for-ai checkout. */ +export function buildAll(sourceDir, cfg) { + const mirrored = new Map(cfg.skills.map((s) => [s.plugin, s.dest])); + const files = new Map(); + for (const entry of cfg.skills) { + const src = join(sourceDir, 'skills', entry.plugin, 'SKILL.md'); + if (!existsSync(src)) throw new Error(`${entry.plugin}: ${src} does not exist in the source checkout`); + files.set(join(OUT_ROOT, entry.dest, 'SKILL.md'), transformSkill(readFileSync(src, 'utf8'), entry, mirrored, cfg)); + } + return files; +} + +/** Previously generated files that the map no longer produces (a skill was removed or renamed). */ +function findOrphans(files, cfg) { + const owned = new Set(cfg.docsOwned.map((d) => join(OUT_ROOT, d, 'SKILL.md'))); + const orphans = []; + const walk = (dir) => { + for (const e of readdirSync(dir, { withFileTypes: true })) { + const p = join(dir, e.name); + if (e.isDirectory()) walk(p); + else if (e.name === 'SKILL.md' && !files.has(p) && !owned.has(p) && /^generated_from:/m.test(readFileSync(p, 'utf8'))) orphans.push(p); + } + }; + if (existsSync(join(OUT_ROOT, 'sdk'))) walk(join(OUT_ROOT, 'sdk')); + return orphans; +} + +function git(args, opts = {}) { + return execFileSync('git', args, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], ...opts }).trim(); +} + +/** Fetch exactly one commit of bugsee-for-ai into a temp dir. */ +function fetchSource(repo, ref) { + const dir = mkdtempSync(join(tmpdir(), 'bugsee-for-ai-')); + git(['init', '-q'], { cwd: dir }); + git(['fetch', '-q', '--depth', '1', repo, ref], { cwd: dir }); + git(['checkout', '-q', 'FETCH_HEAD'], { cwd: dir }); + return dir; +} + +function main() { + const args = process.argv.slice(2); + const flag = (n) => args.includes(n); + const sourceIdx = args.indexOf('--source'); + const localSource = sourceIdx !== -1 ? args[sourceIdx + 1] : null; + const cfg = JSON.parse(readFileSync(MAP_PATH, 'utf8')); + + let ref; + if (localSource) { + ref = 'local'; + } else if (flag('--update')) { + ref = git(['ls-remote', cfg.source.repo, 'refs/heads/main']).split(/\s+/)[0]; + if (!/^[0-9a-f]{40}$/.test(ref)) throw new Error(`could not resolve bugsee-for-ai main (got "${ref}")`); + } else { + ref = JSON.parse(readFileSync(PIN_PATH, 'utf8')).ref; + } + + const tmp = localSource ? null : fetchSource(cfg.source.repo, ref); + let files; + try { + files = buildAll(localSource ?? tmp, cfg); + } finally { + if (tmp) rmSync(tmp, { recursive: true, force: true }); + } + const orphans = findOrphans(files, cfg); + + if (flag('--check')) { + const stale = [...files].filter(([p, c]) => !existsSync(p) || readFileSync(p, 'utf8') !== c).map(([p]) => p); + const bad = [...stale, ...orphans].map((p) => p.replace(ROOT + '/', '')); + if (bad.length) { + console.error(`These generated skill files differ from bugsee-for-ai@${ref.slice(0, 7)}:\n ${bad.join('\n ')}`); + console.error('Do not edit them by hand. Change the skill in bugsee/bugsee-for-ai, or run `npm run mirror-skills`.'); + process.exit(1); + } + console.log(`OK β€” ${files.size} mirrored skills match bugsee-for-ai@${ref.slice(0, 7)}`); + return; + } + + let changed = 0; + for (const [p, c] of files) { + if (existsSync(p) && readFileSync(p, 'utf8') === c) continue; + mkdirSync(dirname(p), { recursive: true }); + writeFileSync(p, c); + changed++; + } + for (const p of orphans) { rmSync(p); changed++; } + if (!localSource && flag('--update')) writeFileSync(PIN_PATH, JSON.stringify({ ref }, null, 2) + '\n'); + console.log(`Mirrored ${files.size} skills from bugsee-for-ai@${ref.slice(0, 7)}; ${changed} file${changed === 1 ? '' : 's'} changed.`); +} + +if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) main(); diff --git a/scripts/mirror-skills.test.mjs b/scripts/mirror-skills.test.mjs new file mode 100644 index 0000000..d610013 --- /dev/null +++ b/scripts/mirror-skills.test.mjs @@ -0,0 +1,76 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { parseSkill, transformSkill, yamlScalar } from './mirror-skills.mjs'; + +const cfg = { + source: { blobBase: 'https://github.com/bugsee/bugsee-for-ai/blob/main', docsBase: 'https://docs.bugsee.com' }, +}; +const entry = { plugin: 'bugsee-flutter-sdk', dest: 'sdk/flutter', title: 'Bugsee Flutter SDK', label: 'Flutter', position: 3 }; +const mirrored = new Map([ + ['bugsee-flutter-sdk', 'sdk/flutter'], + ['bugsee-android-sdk', 'sdk/android/v7'], +]); + +const source = (body, extraFm = '') => `--- +name: bugsee-flutter-sdk +description: Full Bugsee SDK setup for Flutter. Use when asked to add Bugsee. +license: MIT +category: sdk-setup +parent: bugsee-sdk-setup +disable-model-invocation: true +allowed-tools: Bash, Read +${extraFm}--- + +${body}`; + +test('keeps spec fields, adds docusaurus fields, drops plugin-only keys', () => { + const out = transformSkill(source('# Flutter\n'), entry, mirrored, cfg); + const { fm } = parseSkill(out); + assert.equal(fm.name, 'bugsee-flutter-sdk'); + assert.equal(fm.title, 'Bugsee Flutter SDK'); + assert.equal(fm.sidebar_position, '3'); + assert.equal(fm.slug, '"/ai/agent-skills/sdk/flutter/SKILL"'); + assert.equal(fm.license, 'MIT'); + assert.equal(fm.generated_from, 'bugsee-for-ai/skills/bugsee-flutter-sdk/SKILL.md'); + for (const dropped of ['parent', 'disable-model-invocation', 'allowed-tools']) assert.ok(!(dropped in fm), dropped); +}); + +test('strips the plugin breadcrumb', () => { + const out = transformSkill(source('> [All Skills](../../SKILL_TREE.md) > [SDK Setup](../bugsee-sdk-setup/SKILL.md) > Flutter SDK\n\n# Flutter\n'), entry, mirrored, cfg); + assert.ok(!out.includes('All Skills')); + assert.match(out, /---\n\n# Flutter\n$/); +}); + +test('links between mirrored skills stay on docs.bugsee.com; others go to GitHub', () => { + const out = transformSkill( + source('See [Android](../bugsee-android-sdk/SKILL.md#phase-2), [CLI](../bugsee-cli/SKILL.md) and [tree](../../SKILL_TREE.md).\n'), + entry, mirrored, cfg); + assert.match(out, /\]\(https:\/\/docs\.bugsee\.com\/ai\/agent-skills\/sdk\/android\/v7\/SKILL\.md#phase-2\)/); + assert.match(out, /\]\(https:\/\/github\.com\/bugsee\/bugsee-for-ai\/blob\/main\/skills\/bugsee-cli\/SKILL\.md\)/); + assert.match(out, /\]\(https:\/\/github\.com\/bugsee\/bugsee-for-ai\/blob\/main\/SKILL_TREE\.md\)/); +}); + +test('an unhandled relative link fails loudly instead of shipping a dead link', () => { + assert.throws(() => transformSkill(source('[x](./references/foo.md)\n'), entry, mirrored, cfg), /unhandled relative link/); +}); + +test('a skill whose frontmatter name does not match the map is rejected', () => { + assert.throws(() => transformSkill(source('x\n'), { ...entry, plugin: 'bugsee-other-sdk' }, mirrored, cfg), /frontmatter name/); +}); + +test('multi-line frontmatter values are rejected rather than mangled', () => { + assert.throws(() => parseSkill('---\nname: a\ndescription: >\n folded\n---\nbody'), /multi-line/); +}); + +test('yamlScalar quotes only when YAML would misread the value', () => { + assert.equal(yamlScalar('Plain text, with comma.'), 'Plain text, with comma.'); + assert.equal(yamlScalar('has: colon'), '"has: colon"'); + assert.equal(yamlScalar('# starts with hash'), '"# starts with hash"'); + assert.equal(yamlScalar('"already quoted"'), 'already quoted'); +}); + +test('output is deterministic', () => { + const a = transformSkill(source('# Flutter\n'), entry, mirrored, cfg); + const b = transformSkill(source('# Flutter\n'), entry, mirrored, cfg); + assert.equal(a, b); +}); diff --git a/scripts/skills-map.json b/scripts/skills-map.json new file mode 100644 index 0000000..07651c8 --- /dev/null +++ b/scripts/skills-map.json @@ -0,0 +1,22 @@ +{ + "source": { + "repo": "https://github.com/bugsee/bugsee-for-ai.git", + "blobBase": "https://github.com/bugsee/bugsee-for-ai/blob/main", + "docsBase": "https://docs.bugsee.com" + }, + "skills": [ + { "plugin": "bugsee-android-sdk-6x", "dest": "sdk/android", "title": "Bugsee Android SDK 6.x", "label": "Android (6.x)", "position": 1 }, + { "plugin": "bugsee-android-sdk", "dest": "sdk/android/v7", "title": "Bugsee Android SDK 7.x", "label": "Android (7.x)", "position": 2 }, + { "plugin": "bugsee-ios-sdk", "dest": "sdk/ios", "title": "Bugsee iOS SDK", "label": "iOS", "position": 2 }, + { "plugin": "bugsee-flutter-sdk", "dest": "sdk/flutter", "title": "Bugsee Flutter SDK", "label": "Flutter", "position": 3 }, + { "plugin": "bugsee-react-native-sdk","dest": "sdk/react-native", "title": "Bugsee React Native SDK","label": "React Native", "position": 4 }, + { "plugin": "bugsee-unity-sdk", "dest": "sdk/unity", "title": "Bugsee Unity SDK", "label": "Unity", "position": 5 }, + { "plugin": "bugsee-dotnet-sdk", "dest": "sdk/dotnet", "title": "Bugsee .NET SDK", "label": ".NET / MAUI", "position": 6 }, + { "plugin": "bugsee-xamarin-sdk", "dest": "sdk/xamarin", "title": "Bugsee Xamarin SDK", "label": "Xamarin", "position": 7 }, + { "plugin": "bugsee-cordova-sdk", "dest": "sdk/cordova", "title": "Bugsee Cordova SDK", "label": "Cordova", "position": 8 }, + { "plugin": "bugsee-kmp-sdk", "dest": "sdk/kmp", "title": "Bugsee KMP SDK", "label": "KMP", "position": 9 } + ], + "docsOwned": [ + "sdk/ios/v7" + ] +} diff --git a/scripts/skills-source.json b/scripts/skills-source.json new file mode 100644 index 0000000..6463269 --- /dev/null +++ b/scripts/skills-source.json @@ -0,0 +1,3 @@ +{ + "ref": "18c2542292b7a8e38a394d4b0cb06a71d5b24a17" +} From bbdee732ba639ee4807621b97ad0691e10ebc459 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Thu, 8 Oct 2026 17:58:48 +0500 Subject: [PATCH 2/4] chore(ai): refresh static copy of the agent-skills index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generated by scripts/sync-skills.mjs from docs/ai/agent-skills/index.md (Android 6.x / 7.x labels). πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I169dc9b3f89f689f8d866c4f878b9e952b08a65c --- static/ai/agent-skills.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/ai/agent-skills.md b/static/ai/agent-skills.md index 67cbb0b..1b1eb85 100644 --- a/static/ai/agent-skills.md +++ b/static/ai/agent-skills.md @@ -21,8 +21,8 @@ The skill files are structured markdown documents that guide AI agents through p | Platform | Prompt | |----------|--------| -| **Android** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/android/SKILL.md` | -| **Android 7.x (beta)** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/android/v7/SKILL.md` | +| **Android 6.x** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/android/SKILL.md` | +| **Android 7.x** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/android/v7/SKILL.md` | | **iOS** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/ios/SKILL.md` | | **iOS 7.x (beta)** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/ios/v7/SKILL.md` | | **Flutter** | `Use curl to download, read and follow: https://docs.bugsee.com/ai/agent-skills/sdk/flutter/SKILL.md` | From 4991b856ad46ba50f8cea45fc8e2cc93b0f33f72 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Thu, 8 Oct 2026 18:10:45 +0500 Subject: [PATCH 3/4] chore(skills): re-pin to bugsee-for-ai@850ec39 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Picks up the Gradle plugin 4.0.8 pins (bugsee-for-ai#16) and the KMP Verification section (bugsee-for-ai#17). πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I16c0db16a0ddb9062c02db058988305dea0d68f2 --- docs/ai/agent-skills/sdk/android/v7/SKILL.md | 18 ++-- docs/ai/agent-skills/sdk/kmp/SKILL.md | 92 +++++++++++++++++++- scripts/skills-source.json | 2 +- 3 files changed, 101 insertions(+), 11 deletions(-) diff --git a/docs/ai/agent-skills/sdk/android/v7/SKILL.md b/docs/ai/agent-skills/sdk/android/v7/SKILL.md index 5978aeb..b0b17f6 100644 --- a/docs/ai/agent-skills/sdk/android/v7/SKILL.md +++ b/docs/ai/agent-skills/sdk/android/v7/SKILL.md @@ -14,7 +14,7 @@ generated_from: bugsee-for-ai/skills/bugsee-android-sdk/SKILL.md Opinionated wizard that scans the Android project and wires up Bugsee 7.x β€” core SDK, Gradle plugin, extension modules for network clients / Compose / feedback / NDK, APM, and manifest-based auto-launch. -> **7.x is the current Android SDK** (`com.bugsee:bugsee-android:7.3.0`, Gradle plugin `com.bugsee.android.gradle` / `com.bugsee:bugsee-android-gradle-plugin:4.0.7`, re-verified 2026-09-30 on Maven Central and Plugin Portal; SDK lastUpdated 2026-09-29, plugin 2026-09-19) and the default for new and existing apps. Keep the two pins paired β€” the plugin's Compose launch crash fix (4.0.6+) requires SDK 7.1.4+; **7.3.0** satisfies that. **Never pin plugin 4.0.6** β€” it silently disables every SDK extension (see Phase 2). Plugin latest is still **4.0.7** (no 4.0.8+ on either registry; 7.3.0 does not require a plugin bump). 7.3.0 is a security/reliability release β€” upgrade apps on 7.0.0-beta1 through 7.2.0. It is plugin-based with a new API. If you are maintaining an app still pinned to the 6.x line, use the legacy [6.x skill](https://docs.bugsee.com/ai/agent-skills/sdk/android/SKILL.md) instead; when upgrading from 6.x, follow the [migration guide](https://docs.bugsee.com/sdk/android/migration/). +> **7.x is the current Android SDK** (`com.bugsee:bugsee-android:7.3.0`, Gradle plugin `com.bugsee.android.gradle` / `com.bugsee:bugsee-android-gradle-plugin:4.0.8`, re-verified 2026-10-08 on Maven Central; SDK lastUpdated 2026-09-29, plugin 2026-10-08) and the default for new and existing apps. Keep the two pins paired β€” the plugin's Compose launch crash fix (4.0.6+) requires SDK 7.1.4+; **7.3.0** satisfies that. **Never pin plugin 4.0.6** β€” it silently disables every SDK extension (see Phase 2). Plugin latest is **4.0.8** (7.3.0 does not require a plugin bump). 7.3.0 is a security/reliability release β€” upgrade apps on 7.0.0-beta1 through 7.2.0. It is plugin-based with a new API. If you are maintaining an app still pinned to the 6.x line, use the legacy [6.x skill](https://docs.bugsee.com/ai/agent-skills/sdk/android/SKILL.md) instead; when upgrading from 6.x, follow the [migration guide](https://docs.bugsee.com/sdk/android/migration/). ## Invoke This Skill When @@ -89,7 +89,7 @@ Decision table: ### Step 1 β€” Apply the Bugsee Gradle plugin (mandatory) -7.x requires the plugin. Without it, APM, main-thread misuse detection, log capture rewrites, OkHttp injection, and Compose secure redaction do not work. Pin plugin **4.0.7** with SDK **7.3.0** (plugin still the current Plugin Portal / Maven release as of 2026-09-30; keep the two pins paired). Plugin 4.x pairs with SDK 7.x; do not mix with plugin 3.x / SDK 6.x. There is no separate Gradle-plugin skill β€” apply the notes below from the [plugin release notes](https://docs.bugsee.com/sdk/android/gradle-plugin/releases/). +7.x requires the plugin. Without it, APM, main-thread misuse detection, log capture rewrites, OkHttp injection, and Compose secure redaction do not work. Pin plugin **4.0.8** with SDK **7.3.0** (current Maven Central release as of 2026-10-08; keep the two pins paired). Do not stay on 4.0.7: it pins bugsee-cli 0.6.0, which silently uploads nothing for NDK `SYMBOL_TABLE` symbols when the CLI's auto-update is off or its download host is unreachable; 4.0.8 pins bugsee-cli 0.8.1. Plugin 4.x pairs with SDK 7.x; do not mix with plugin 3.x / SDK 6.x. There is no separate Gradle-plugin skill β€” apply the notes below from the [plugin release notes](https://docs.bugsee.com/sdk/android/gradle-plugin/releases/). **Kotlin DSL (`app/build.gradle.kts`):** @@ -97,7 +97,7 @@ Decision table: plugins { id("com.android.application") id("org.jetbrains.kotlin.android") - id("com.bugsee.android.gradle") version "4.0.7" + id("com.bugsee.android.gradle") version "4.0.8" } bugsee { @@ -125,7 +125,7 @@ bugsee { plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' - id 'com.bugsee.android.gradle' version '4.0.7' + id 'com.bugsee.android.gradle' version '4.0.8' } bugsee { @@ -148,13 +148,13 @@ pluginManagement { With the plugin applied, the core `com.bugsee:bugsee-android` artifact is auto-pulled (bounded to the same MAJOR.MINOR series as the plugin's `sdk-min-version`). Dependency-driven extensions (OkHttp, Ktor 2/3, Cronet, Compose) are auto-installed when the matching library is in the graph. Feedback, NDK, and leak are **not** dependency-driven β€” enable them with the DSL toggles above. -From plugin **4.0.6** (carried into 4.0.7): variants that do **not** include Bugsee (e.g. `debugImplementation` only) are no longer instrumented or wired. Flavors are handled the same way. Plain `implementation` is unchanged β€” do not invent extra plugin flags for that case. The Compose launch crash fix requires SDK **7.1.4+**; **7.3.0** satisfies that β€” do not pair plugin 4.0.6+ with an older 7.1.x SDK. No DSL changes. Plugin latest is still **4.0.7** (Maven Central / Plugin Portal lastUpdated 2026-09-19; re-verified 2026-09-30). +From plugin **4.0.6** (carried into 4.0.7 and 4.0.8): variants that do **not** include Bugsee (e.g. `debugImplementation` only) are no longer instrumented or wired. Flavors are handled the same way. Plain `implementation` is unchanged β€” do not invent extra plugin flags for that case. The Compose launch crash fix requires SDK **7.1.4+**; **7.3.0** satisfies that β€” do not pair plugin 4.0.6+ with an older 7.1.x SDK. No DSL changes. Plugin latest is **4.0.8** (Maven Central lastUpdated 2026-10-08; re-verified 2026-10-08). > **Plugin 4.0.6 is broken β€” upgrade it on sight.** In apps built against the published SDK, 4.0.6 stripped the extension providers from the manifest without registering the extensions in their place: **NDK crash reporting, feedback, Compose, OkHttp, Ktor, Cronet and leak detection never ran**, with a green build and a normally working app. Because the Compose extension never installed, content marked `bugseeSecure` was **not masked** in report screenshots. 4.0.7 fixes it. If an app is on 4.0.6 and cannot move yet, stay on 4.0.5 or set `optimizeExtensionsLoading.set(false)` in `bugsee {}`. Also in 4.0.7 ([release notes](https://docs.bugsee.com/sdk/android/gradle-plugin/releases/)): > - Only Bugsee's own extension providers are consolidated β€” a `BugseeInitProvider` in the app or a wrapper SDK is no longer silently removed (4.0.0-beta10 β†’ 4.0.6 removed them). > - If the plugin would strip extension providers it cannot register (e.g. an SDK older than 7.0.0-beta11 declared with a non-literal version such as `7.+`), the build now **fails** naming the providers and pointing at `optimizeExtensionsLoading` β€” that error means "pin a literal SDK version", not "disable the plugin". > - The built-in fallback uploader treats the server's "already uploaded" reply as success, so an unchanged mapping is no longer re-uploaded on every build. -> - The auto-added SDK floor is still 7.2.0 (plugin 4.0.7). Auto-pull on `[7.2.0,8.0.0)` can resolve 7.3.0, but pin **7.3.0** explicitly so the security release is locked. +> - The auto-added SDK floor is still 7.2.0 (plugin 4.0.8). Auto-pull on `[7.2.0,8.0.0)` can resolve 7.3.0, but pin **7.3.0** explicitly so the security release is locked. ### Step 2 β€” Pin the core SDK (recommended) @@ -181,9 +181,9 @@ dependencies { To suppress auto-install of a dependency-driven extension, set the corresponding flag in `bugsee { instrumentation { ... } }` (e.g. `cronet.set(false)`). To opt out of core auto-pull entirely, `sdkAutoLoad.set(false)`. -> **Current stable releases (re-verified 2026-09-30 against Maven Central and Plugin Portal; SDK lastUpdated 2026-09-29):** SDK `com.bugsee:bugsee-android:7.3.0` (and matching `bugsee-android-compose`, `bugsee-android-ndk`, `bugsee-android-feedback`, `bugsee-android-okhttp`, `bugsee-android-ktor-2`, `bugsee-android-ktor-3`, `bugsee-android-cronet`, `bugsee-android-leak` at **7.3.0**) and Gradle plugin `4.0.7` (`com.bugsee:bugsee-android-gradle-plugin` / Plugin Portal `com.bugsee.android.gradle`; plugin lastUpdated 2026-09-19). The plugin tracks its own 4.x line, separate from the SDK β€” pin both together. 7.3.0 does not require a plugin bump. +> **Current stable releases (re-verified 2026-10-08 against Maven Central; SDK lastUpdated 2026-09-29):** SDK `com.bugsee:bugsee-android:7.3.0` (and matching `bugsee-android-compose`, `bugsee-android-ndk`, `bugsee-android-feedback`, `bugsee-android-okhttp`, `bugsee-android-ktor-2`, `bugsee-android-ktor-3`, `bugsee-android-cronet`, `bugsee-android-leak` at **7.3.0**) and Gradle plugin `4.0.8` (`com.bugsee:bugsee-android-gradle-plugin` / Plugin Portal `com.bugsee.android.gradle`; plugin lastUpdated 2026-10-08). The plugin tracks its own 4.x line, separate from the SDK β€” pin both together. 7.3.0 does not require a plugin bump. > -> **SDK 7.3.0 / plugin 4.0.7 β€” cite, do not invent APIs.** [Android SDK 7.3.0](https://docs.bugsee.com/sdk/android/release-notes/) is a security and reliability release; the public API is **additive**. [Gradle plugin 4.0.7](https://docs.bugsee.com/sdk/android/gradle-plugin/releases/) remains the latest fix release β€” no DSL changes. Agents should **not** advise workarounds 7.1.4 / 4.0.6 made unnecessary: +> **SDK 7.3.0 / plugin 4.0.8 β€” cite, do not invent APIs.** [Android SDK 7.3.0](https://docs.bugsee.com/sdk/android/release-notes/) is a security and reliability release; the public API is **additive**. [Gradle plugin 4.0.8](https://docs.bugsee.com/sdk/android/gradle-plugin/releases/) is the latest release (it adopts bugsee-cli 0.8.1 and fixes NDK symbol uploads). Agents should **not** advise workarounds 7.1.4 / 4.0.6 made unnecessary: > - **Upgrade from 7.2.0 (and any 7.0.0-beta1+).** The SDK internal log attached to reports no longer records app HTTP URLs (including embedded credentials and query strings), `setUserIdentifier` / `setAttribute` values, performance-transaction URLs, or filter/listener text. Data written by an earlier 7.x is deleted on the first 7.3.0 launch and never attached. Recommend the upgrade; do not invent a third-party leak β€” it stayed in the app's own Bugsee project. > - **Ktor.** 7.2.0 `bugsee-android-ktor-2` / `bugsee-android-ktor-3` did not compile `install(BugseeKtor2Plugin)`, `install(BugseeKtor3Plugin.Plugin)`, or `bugseeWebSocket` in Kotlin apps. Pin **7.3.0**. > - **Pending-report caps (defaults on).** `MaxDataSize` (150 MB), `MaxPendingReports` (30), `MaxPendingReportAge` (30 days). Past a limit, oldest unsent reports are deleted (errors before bugs before crashes). A device offline more than 30 days now drops the oldest instead of keeping them all. @@ -302,7 +302,7 @@ Native crash detection is **not** in the core artifact. Enable it with the plugi ### WebSocket -OkHttp `newWebSocket(...)` traffic (connection lifecycle, frames, close/error) is captured automatically when the OkHttp extension is installed (Gradle plugin **4.0.3+**; use 4.0.7 β€” 4.0.6 never registered the OkHttp extension). Ktor on the OkHttp engine is automatic; on CIO, route calls through the `bugseeWebSocket` helper. `NetworkEventStage.WebSocket` is the stage value for custom events. +OkHttp `newWebSocket(...)` traffic (connection lifecycle, frames, close/error) is captured automatically when the OkHttp extension is installed (Gradle plugin **4.0.3+**; use 4.0.8 β€” 4.0.6 never registered the OkHttp extension). Ktor on the OkHttp engine is automatic; on CIO, route calls through the `bugseeWebSocket` helper. `NetworkEventStage.WebSocket` is the stage value for custom events. ### `FLAG_SECURE` diff --git a/docs/ai/agent-skills/sdk/kmp/SKILL.md b/docs/ai/agent-skills/sdk/kmp/SKILL.md index 7ac9666..b290524 100644 --- a/docs/ai/agent-skills/sdk/kmp/SKILL.md +++ b/docs/ai/agent-skills/sdk/kmp/SKILL.md @@ -206,7 +206,7 @@ For readable stack traces from release builds, upload platform debug symbols. Th In a typical KMP/Compose Multiplatform project, wire the Bugsee Gradle plugin into `composeApp/build.gradle.kts`. **Match the plugin line to the native Android SDK the KMP release wraps** β€” lines are not cross-compatible ([requirements](https://docs.bugsee.com/sdk/android/gradle-plugin/requirements/)): plugin **3.x ↔ SDK 6.x**, plugin **4.x ↔ SDK 7.x**. -KMP **0.1.2** wraps native Android SDK **6.0.4** (its Maven POM's `com.bugsee:bugsee-android` dependency; check the [KMP release notes](https://docs.bugsee.com/sdk/kmp/release-notes/) for later releases), so pin plugin **3.6** β€” the latest 3.x β€” and use the boolean `ndk(true)`. **Do not** reach for plugin 4.x here: it expects the 7.x module layout, auto-pulls `com.bugsee:bugsee-android` on the 7.x range, and its nested `ndk { enabled.set(true) }` block does not exist on 3.x (using it there fails with `Type mismatch: inferred type is () -> Unit but Boolean was expected`). Once a KMP release wraps SDK 7.x, switch to plugin 4.0.7 (never 4.0.6) and the nested block β€” see [`bugsee-android-sdk`](https://docs.bugsee.com/ai/agent-skills/sdk/android/v7/SKILL.md). +KMP **0.1.2** wraps native Android SDK **6.0.4** (its Maven POM's `com.bugsee:bugsee-android` dependency; check the [KMP release notes](https://docs.bugsee.com/sdk/kmp/release-notes/) for later releases), so pin plugin **3.6** β€” the latest 3.x β€” and use the boolean `ndk(true)`. **Do not** reach for plugin 4.x here: it expects the 7.x module layout, auto-pulls `com.bugsee:bugsee-android` on the 7.x range, and its nested `ndk { enabled.set(true) }` block does not exist on 3.x (using it there fails with `Type mismatch: inferred type is () -> Unit but Boolean was expected`). Once a KMP release wraps SDK 7.x, switch to plugin 4.0.8 (never 4.0.6) and the nested block β€” see [`bugsee-android-sdk`](https://docs.bugsee.com/ai/agent-skills/sdk/android/v7/SKILL.md). ```kotlin // gradle/libs.versions.toml @@ -251,6 +251,96 @@ If editing `.xcscheme` XML is awkward β€” a generated `iosApp` project, or a CI- --- +## Verification + +Build and run the app on both an Android device/emulator and an iOS device/simulator, then work through the steps below. + +### 1. Confirm the SDK actually started + +```kotlin +import com.bugsee.kmp.Bugsee + +// Anywhere after launch(), from commonMain +println("Bugsee launched: ${Bugsee.isLaunched()}") +``` + +`Bugsee.isLaunched()` is backed by the native SDKs on both targets, so `false` means `launch()` bailed out rather than that the check is unsupported. + +### 2. File a test report + +The default trigger gesture differs per platform β€” `BugseeLaunchOptions` defaults `shakeToReport` to `true` on Android and `screenshotToReport` to `true` on iOS: + +- **Android** β€” shake the device +- **iOS** β€” take a screenshot + +Or trigger the dialog from shared code, which works on both: + +```kotlin +import com.bugsee.kmp.Bugsee +import com.bugsee.kmp.BugseeSeverity + +Bugsee.showReportDialog() + +// Or pre-filled +Bugsee.showReportDialog("Smoke test", "Verifying Bugsee KMP setup", BugseeSeverity.Medium) +``` + +Valid `BugseeSeverity` values are `VeryLow`, `Medium`, `High`, `Critical`, and `Blocker`. + +### 3. Verify exception and crash capture + +A handled exception is the safest check β€” it does not terminate the app: + +```kotlin +try { + (null as String?)!!.length +} catch (ex: Exception) { + Bugsee.logException(ex) +} +``` + +For an uncaught crash, be aware of a Compose Multiplatform gotcha: on Android a throwable raised synchronously inside a `Modifier.clickable` lambda is absorbed by the pointer-input coroutine and never reaches `Thread.UncaughtExceptionHandler`, so Bugsee cannot capture it. Throw from a background thread instead β€” this works uniformly on both targets: + +```kotlin +// commonMain +expect fun runOnBackgroundThread(block: () -> Unit) + +// androidMain β€” the throwable reaches AndroidRuntime and Bugsee +actual fun runOnBackgroundThread(block: () -> Unit) { + Thread { block() }.start() +} + +// iosMain β€” the throwable goes through Kotlin/Native's unhandled-exception hook, +// which Bugsee installs on successful launch when crashReport is enabled +@OptIn(ExperimentalForeignApi::class) +actual fun runOnBackgroundThread(block: () -> Unit) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT.toLong(), 0u)) { + block() + } +} + +// Test: remove after verifying +runOnBackgroundThread { throw RuntimeException("Bugsee KMP smoke test") } +``` + +Relaunch the app afterwards β€” crash reports are uploaded on the next start. + +### 4. If nothing arrives + +**Android** β€” check logcat for the KMP layer's own diagnostics: + +```bash +adb logcat -s BugseeInternal +``` + +`Bugsee KMP: cannot launch() β€” applicationContext is not gathered` means `launch()` ran before the SDK's internal `ContentProvider` captured the application context. Call `launch()` from `Application.onCreate()` (not `attachBaseContext()`), and confirm `android:name` on the `` tag actually points at your `Application` subclass. + +**iOS** β€” the KMP layer logs through `NSLog` with a `DEBUG: [BugseeInternal] …` / `ERROR: [BugseeInternal] …` prefix. Filter the Xcode console for `BugseeInternal`. + +Finally, check the Bugsee dashboard for the incoming reports. + +--- + ## Documentation Links - [Installation](https://docs.bugsee.com/sdk/kmp/installation/) diff --git a/scripts/skills-source.json b/scripts/skills-source.json index 6463269..0d61501 100644 --- a/scripts/skills-source.json +++ b/scripts/skills-source.json @@ -1,3 +1,3 @@ { - "ref": "18c2542292b7a8e38a394d4b0cb06a71d5b24a17" + "ref": "850ec39aa05e27d881a2687ee58e5c8712d2a5d8" } From cbfdb85965e4c5bd01e75c8e625f59c32c021b3e Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Thu, 8 Oct 2026 18:18:35 +0500 Subject: [PATCH 4/4] ci(skills-sync): authenticate as a GitHub App instead of a stored PAT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mint a short-lived installation token per run (actions/create-github-app-token, pinned to a commit) for opening the sync PR, so the credential is not tied to a person and the PR triggers the normal checks. Falls back to GITHUB_TOKEN while the app is not configured. πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Idf302f0d6d8648f1e17c4e20e9377d46c7397344 --- .github/workflows/sync-agent-skills.yml | 26 ++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/.github/workflows/sync-agent-skills.yml b/.github/workflows/sync-agent-skills.yml index 4e50979..3c96c5e 100644 --- a/.github/workflows/sync-agent-skills.yml +++ b/.github/workflows/sync-agent-skills.yml @@ -13,10 +13,13 @@ name: Sync agent skills # # One-time setup (see the PR that introduced this file): # * Settings > Actions > General > "Allow GitHub Actions to create and approve pull requests". -# * Optional but recommended: a SKILLS_SYNC_TOKEN secret (fine-grained PAT or GitHub App token -# with Contents + Pull requests write on this repo). PRs opened with the default GITHUB_TOKEN do -# not trigger the "Build and Deploy" checks; this job therefore runs the spell check and the -# site build itself and opens the PR as a DRAFT if either fails. +# * Recommended: a GitHub App (owned by the org, not a person) installed on this repo with +# Contents + Pull requests: write. Set its client ID as the repository VARIABLE +# SYNC_APP_CLIENT_ID and its private key as the repository SECRET SYNC_APP_PRIVATE_KEY. The job +# then mints a short-lived token per run, and the sync PR gets the normal "Build and Deploy" +# checks. Without the app it falls back to GITHUB_TOKEN: PRs opened that way do not trigger +# other workflows, so this job runs the spell check and the site build itself and opens the PR +# as a DRAFT if either fails. on: repository_dispatch: @@ -36,6 +39,9 @@ concurrency: jobs: sync: runs-on: ubuntu-latest + env: + SYNC_APP_CLIENT_ID: ${{ vars.SYNC_APP_CLIENT_ID }} + SYNC_APP_PRIVATE_KEY: ${{ secrets.SYNC_APP_PRIVATE_KEY }} steps: - name: Checkout uses: actions/checkout@v7 @@ -103,11 +109,21 @@ jobs: echo "πŸ€– Generated with [Claude Code](https://claude.com/claude-code)" } > pr-body.md + - name: Mint a short-lived GitHub App token + id: app + if: steps.mirror.outputs.changed == 'true' && env.SYNC_APP_CLIENT_ID != '' && env.SYNC_APP_PRIVATE_KEY != '' + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + client-id: ${{ vars.SYNC_APP_CLIENT_ID }} + private-key: ${{ secrets.SYNC_APP_PRIVATE_KEY }} + permission-contents: write + permission-pull-requests: write + - name: Open or update the sync PR if: steps.mirror.outputs.changed == 'true' uses: peter-evans/create-pull-request@v8.1.1 with: - token: ${{ secrets.SKILLS_SYNC_TOKEN || secrets.GITHUB_TOKEN }} + token: ${{ steps.app.outputs.token || secrets.GITHUB_TOKEN }} branch: automation/sync-agent-skills delete-branch: true add-paths: |