{"owner":"duckduckgo","repo":"Android","hasSkills":true,"totalSkillsCount":5,"totalTokensCount":3093,"categories":["root-instruction","mcp-config","marketplace","plugin-manifest","cursor-rule"],"hasMcp":true,"mcpConfig":{"mcpServers":{"Android":{"command":"npx","args":["-y","@modelcontextprotocol/server-Android"]}}},"found":["AGENTS.md",".cursor/mcp.json",".claude-plugin/marketplace.json",".claude-plugin/plugin.json",".cursorrules (android-jetpack-compose-cursorrules-prompt-file.mdc)"],"skills":{"AGENTS.md":"# AGENTS.md — DuckDuckGo Android Browser\n\nDuckDuckGo Android is a privacy-focused browser built as a large multi-module Gradle project,\nproviding built-in search, tracker blocking, HTTPS enforcement and other privacy features.\n\n**Versions** (SDK levels, Kotlin, Gradle, libraries) live in the build files — don't restate them here:\n`min_sdk` / `target_sdk` / `compile_sdk` in `build.gradle`, `version.kotlin` in `versions.properties`,\nand the Gradle version in `gradle/wrapper/gradle-wrapper.properties`.\n**Build:** AGP via refreshVersions. DI is **Metro** (KSP generators in `:codegen-ksp`; see `.claude/docs/architecture.md`).\n**Toolchain:** Kotlin JVM target 17; building requires **JDK 21** (Metro compiler plugin).\n\nNotable libraries: Room, Retrofit/OkHttp/Moshi, Coroutines, Jetpack Compose (selective), WorkManager,\n`logcat` (Square), KSP for annotation processing. Versions are in `versions.properties` and the module\n`build.gradle` files.\n\n---\n\n## Privacy invariants for anything leaving the device\n\nThis is a privacy browser; these hold for every outbound value — pixels, wide events, logs, crash\nreports, debug output — not just telemetry you are deliberately designing.\n\n- **No PII.** Never emails, names, account IDs, usernames or phone numbers, in a name or a value.\n- **No URLs, domains or page titles.** Breakage reports are the one controlled exception, with explicit\n  user consent.\n- **No correlation IDs.** No session IDs, GUIDs or exact timestamps — anything that links events to one\n  user session.\n- **Bucket numeric values.** Exact durations, byte counts and item counts fingerprint users; send ranges.\n- **Bounded enums over free-form strings.** High-cardinality unbounded strings are both a privacy risk\n  and unanalysable.\n\nAdding or changing a pixel or the pixel registry also requires privacy triage — see\n`.claude/docs/pixels.md`.\n\n---\n\n## Read these when the situation applies\n\nThese files are not in context. Read the whole file before doing the work it covers — don't rely on\nwhat you remember of it.\n\n| Read | When |\n|---|---|\n| `.claude/docs/architecture.md` | **planning or implementing** any new code, refactoring, or module changes — `-api`/`-impl` structure, DI scopes, navigation, coroutine job patterns |\n| `.claude/docs/android-design-system.md` | **planning or implementing** any UI — which ADS component to use, colors, spacing; raw Android/Material widgets are lint-blocked |\n| `.claude/docs/contributions.md` | **planning** a change that touches a `-api` surface or spans multiple modules — it needs an approved API Proposal and/or Tech Design, and that has to be raised before implementation, not at PR time. Also read it when naming a branch, writing a commit, or opening a PR |\n| `.claude/docs/lateinit-hazards.md` | writing or reviewing any `lateinit var`, especially `@Inject lateinit var` in a View |\n| `.claude/docs/plugin-system.md` | declaring a plugin point or contributing a plugin (`PluginPoint` / `ActivePluginPoint`) |\n| `.claude/docs/native-input.md` | **changing** the native input (`NativeInputModeWidget`, its plugins and footers, `NativeInputManager`, the contextual sheet or the edit screen) — adding a control, state-store rules, host gotchas, and the refactor still in flight |\n| `.claude/docs/pixels.md` | adding or changing pixel telemetry — including whether a pixel or a wide event is the right instrument |\n| `.claude/docs/di-scopes.md` | an injection fails at runtime (\"Could not find the injector\"), or you're deciding which scope to pass to `@InjectWith` — has the component/subcomponent diagram and the `injectorFactoryMap` lookups |\n| `.claude/docs/navigation.md` | adding a screen or navigating to one — `ActivityParams`, `@ContributeToActivityStarter`, deeplinks, and which `GlobalActivityStarter` overload to use |\n| `.claude/docs/url-classification.md` | routing typed input to navigation vs search — use `QueryUrlPredictor`, not `UriString.isWebUrl()` |\n| `.claude/docs/icons.md` | the change needs an icon the project doesn't have yet — it must be fetched from the internal Icons repository, never invented |\n| `.claude/docs/translations.md` | adding or changing any user-facing string — `donottranslate.xml` vs `strings-<module>.xml`, placeholder/`instruction` rules, how to change or remove already-translated copy |\n\n---\n\n## Build & Test Commands\n\n```bash\n# Unit tests (all modules)\n./gradlew jvm_tests\n\n# Unit tests for a single module\n./gradlew :my-feature-impl:testDebugUnitTest\n\n# Code quality (spotless + lint + unit tests)\n./gradlew jvm_checks\n\n# Lint only\n./gradlew lint_check\n\n# Code formatting check / fix\n./gradlew spotlessCheck\n./gradlew spotlessApply\n\n# Install app\n./gradlew installInternalRelease    # internal build (more testing features)\n./gradlew installPlayRelease        # play store build\n```\n\n`jvm_tests` and `jvm_checks` resolve to `testPlayDebugUnitTest` in `:app` and `testDebugUnitTest` in\nlibrary modules. To run a single test class, use `--tests`:\n\n```bash\n./gradlew :my-feature-impl:testDebugUnitTest --tests \"com.duckduckgo.my.feature.RealFooTest\"\n```\n\n### Build Variants\n\n| Dimension | Flavors |\n|---|---|\n| store | `internal`, `fdroid`, `play` |\n| Build types | `debug`, `release`, `upload` |\n\n### Proprietary Fonts\n\nThe app uses a proprietary DuckSans font from a private GitHub Packages repository. The build\nconditionally swaps between the proprietary `ddg-proprietary-fonts` AAR and a local `:fonts` fallback\nmodule (empty `<font-family/>` stubs) based on credential availability. See `build.gradle` for the\ncredential detection logic and `android-design-system/fonts/readme.md` for details.\n\n---\n\n## Code Formatting\n\n- **Spotless** with ktlint for Kotlin; Google Java Format in AOSP style for Java\n- Max line length: 150 characters\n- Ratchet from `origin/develop` — only changed code is enforced\n\n---\n\n## Code Comments\n\nComments explain the **why** (intent, assumptions, non-obvious decisions), not the **what** the code\nalready shows.\n\nDefault to no comment: prefer self-documenting code (clear names, small functions), and add one only\nwhere code alone can't carry the reasoning, and only if it still answers *\"why was this done this\nway?\"* for someone reading it two years from now. `-api` module declarations may carry KDoc describing\nthe contract — that's documentation for consumers, not narration.\n\nNever add:\n\n- **narration** of trivial code\n- **conversational / temporal residue**\n- **process / plan references**\n\n```kotlin\ncount++ // increment the counter -> narration of trivial code\nval user = repo.load() // fixes the bug from the previous task -> temporal residue\nval state = flow // changed from LiveData -> temporal residue\ncache.clear() // step 3 of the plan -> process / plan reference\nretryCount = 3 // per the Asana task -> process / plan reference\n```\n\nWhen reviewing a diff, flag any added comment that doesn't follow these rules.\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.claude-plugin/plugin.json)",".cursorrules (android-jetpack-compose-cursorrules-prompt-file.mdc)":"---\ndescription: \"Cursor rules for Android development with Jetpack Compose integration.\"\nglobs: **/*\nalwaysApply: false\n---\n// Android Jetpack Compose .cursorrules\n\n// Flexibility Notice\n\n// Note: This is a recommended project structure, but be flexible and adapt to existing project structures.\n// Do not enforce these structural patterns if the project follows a different organization.\n// Focus on maintaining consistency with the existing project architecture while applying Jetpack Compose best practices.\n\n// Project Architecture and Best Practices\n\nconst androidJetpackComposeBestPractices = [\n    \"Adapt to existing project architecture while maintaining clean code principles\",\n    \"Follow Material Design 3 guidelines and components\",\n    \"Implement clean architecture with domain, data, and presentation layers\",\n    \"Use Kotlin coroutines and Flow for asynchronous operations\",\n    \"Implement dependency injection using Hilt\",\n    \"Follow unidirectional data flow with ViewModel and UI State\",\n    \"Use Compose navigation for screen management\",\n    \"Implement proper state hoisting and composition\",\n];\n\n// Folder Structure\n\n// Note: This is a reference structure. Adapt to the project's existing organization\n\nconst projectStructure = `\napp/\n  src/\n    main/\n      java/com/package/\n        data/\n          repository/\n          datasource/\n          models/\n        domain/\n          usecases/\n          models/\n          repository/\n        presentation/\n          screens/\n          components/\n          theme/\n          viewmodels/\n        di/\n        utils/\n      res/\n        values/\n        drawable/\n        mipmap/\n    test/\n    androidTest/\n`;\n\n// Compose UI Guidelines\n\nconst composeGuidelines = `\n1. Use remember and derivedStateOf appropriately\n2. Implement proper recomposition optimization\n3. Use proper Compose modifiers ordering\n4. Follow composable function naming conventions\n5. Implement proper preview annotations\n6. Use proper state management with MutableState\n7. Implement proper error handling and loading states\n8. Use proper theming with MaterialTheme\n9. Follow accessibility guidelines\n10. Implement proper animation patterns\n`;\n\n// Testing Guidelines\n\nconst testingGuidelines = `\n1. Write unit tests for ViewModels and UseCases\n2. Implement UI tests using Compose testing framework\n3. Use fake repositories for testing\n4. Implement proper test coverage\n5. Use proper testing coroutine dispatchers\n`;\n\n// Performance Guidelines\n\nconst performanceGuidelines = `\n1. Minimize recomposition using proper keys\n2. Use proper lazy loading with LazyColumn and LazyRow\n3. Implement efficient image loading\n4. Use proper state management to prevent unnecessary updates\n5. Follow proper lifecycle awareness\n6. Implement proper memory management\n7. Use proper background processing\n`;\n"},"files":{"AGENTS.md":"# AGENTS.md — DuckDuckGo Android Browser\n\nDuckDuckGo Android is a privacy-focused browser built as a large multi-module Gradle project,\nproviding built-in search, tracker blocking, HTTPS enforcement and other privacy features.\n\n**Versions** (SDK levels, Kotlin, Gradle, libraries) live in the build files — don't restate them here:\n`min_sdk` / `target_sdk` / `compile_sdk` in `build.gradle`, `version.kotlin` in `versions.properties`,\nand the Gradle version in `gradle/wrapper/gradle-wrapper.properties`.\n**Build:** AGP via refreshVersions. DI is **Metro** (KSP generators in `:codegen-ksp`; see `.claude/docs/architecture.md`).\n**Toolchain:** Kotlin JVM target 17; building requires **JDK 21** (Metro compiler plugin).\n\nNotable libraries: Room, Retrofit/OkHttp/Moshi, Coroutines, Jetpack Compose (selective), WorkManager,\n`logcat` (Square), KSP for annotation processing. Versions are in `versions.properties` and the module\n`build.gradle` files.\n\n---\n\n## Privacy invariants for anything leaving the device\n\nThis is a privacy browser; these hold for every outbound value — pixels, wide events, logs, crash\nreports, debug output — not just telemetry you are deliberately designing.\n\n- **No PII.** Never emails, names, account IDs, usernames or phone numbers, in a name or a value.\n- **No URLs, domains or page titles.** Breakage reports are the one controlled exception, with explicit\n  user consent.\n- **No correlation IDs.** No session IDs, GUIDs or exact timestamps — anything that links events to one\n  user session.\n- **Bucket numeric values.** Exact durations, byte counts and item counts fingerprint users; send ranges.\n- **Bounded enums over free-form strings.** High-cardinality unbounded strings are both a privacy risk\n  and unanalysable.\n\nAdding or changing a pixel or the pixel registry also requires privacy triage — see\n`.claude/docs/pixels.md`.\n\n---\n\n## Read these when the situation applies\n\nThese files are not in context. Read the whole file before doing the work it covers — don't rely on\nwhat you remember of it.\n\n| Read | When |\n|---|---|\n| `.claude/docs/architecture.md` | **planning or implementing** any new code, refactoring, or module changes — `-api`/`-impl` structure, DI scopes, navigation, coroutine job patterns |\n| `.claude/docs/android-design-system.md` | **planning or implementing** any UI — which ADS component to use, colors, spacing; raw Android/Material widgets are lint-blocked |\n| `.claude/docs/contributions.md` | **planning** a change that touches a `-api` surface or spans multiple modules — it needs an approved API Proposal and/or Tech Design, and that has to be raised before implementation, not at PR time. Also read it when naming a branch, writing a commit, or opening a PR |\n| `.claude/docs/lateinit-hazards.md` | writing or reviewing any `lateinit var`, especially `@Inject lateinit var` in a View |\n| `.claude/docs/plugin-system.md` | declaring a plugin point or contributing a plugin (`PluginPoint` / `ActivePluginPoint`) |\n| `.claude/docs/native-input.md` | **changing** the native input (`NativeInputModeWidget`, its plugins and footers, `NativeInputManager`, the contextual sheet or the edit screen) — adding a control, state-store rules, host gotchas, and the refactor still in flight |\n| `.claude/docs/pixels.md` | adding or changing pixel telemetry — including whether a pixel or a wide event is the right instrument |\n| `.claude/docs/di-scopes.md` | an injection fails at runtime (\"Could not find the injector\"), or you're deciding which scope to pass to `@InjectWith` — has the component/subcomponent diagram and the `injectorFactoryMap` lookups |\n| `.claude/docs/navigation.md` | adding a screen or navigating to one — `ActivityParams`, `@ContributeToActivityStarter`, deeplinks, and which `GlobalActivityStarter` overload to use |\n| `.claude/docs/url-classification.md` | routing typed input to navigation vs search — use `QueryUrlPredictor`, not `UriString.isWebUrl()` |\n| `.claude/docs/icons.md` | the change needs an icon the project doesn't have yet — it must be fetched from the internal Icons repository, never invented |\n| `.claude/docs/translations.md` | adding or changing any user-facing string — `donottranslate.xml` vs `strings-<module>.xml`, placeholder/`instruction` rules, how to change or remove already-translated copy |\n\n---\n\n## Build & Test Commands\n\n```bash\n# Unit tests (all modules)\n./gradlew jvm_tests\n\n# Unit tests for a single module\n./gradlew :my-feature-impl:testDebugUnitTest\n\n# Code quality (spotless + lint + unit tests)\n./gradlew jvm_checks\n\n# Lint only\n./gradlew lint_check\n\n# Code formatting check / fix\n./gradlew spotlessCheck\n./gradlew spotlessApply\n\n# Install app\n./gradlew installInternalRelease    # internal build (more testing features)\n./gradlew installPlayRelease        # play store build\n```\n\n`jvm_tests` and `jvm_checks` resolve to `testPlayDebugUnitTest` in `:app` and `testDebugUnitTest` in\nlibrary modules. To run a single test class, use `--tests`:\n\n```bash\n./gradlew :my-feature-impl:testDebugUnitTest --tests \"com.duckduckgo.my.feature.RealFooTest\"\n```\n\n### Build Variants\n\n| Dimension | Flavors |\n|---|---|\n| store | `internal`, `fdroid`, `play` |\n| Build types | `debug`, `release`, `upload` |\n\n### Proprietary Fonts\n\nThe app uses a proprietary DuckSans font from a private GitHub Packages repository. The build\nconditionally swaps between the proprietary `ddg-proprietary-fonts` AAR and a local `:fonts` fallback\nmodule (empty `<font-family/>` stubs) based on credential availability. See `build.gradle` for the\ncredential detection logic and `android-design-system/fonts/readme.md` for details.\n\n---\n\n## Code Formatting\n\n- **Spotless** with ktlint for Kotlin; Google Java Format in AOSP style for Java\n- Max line length: 150 characters\n- Ratchet from `origin/develop` — only changed code is enforced\n\n---\n\n## Code Comments\n\nComments explain the **why** (intent, assumptions, non-obvious decisions), not the **what** the code\nalready shows.\n\nDefault to no comment: prefer self-documenting code (clear names, small functions), and add one only\nwhere code alone can't carry the reasoning, and only if it still answers *\"why was this done this\nway?\"* for someone reading it two years from now. `-api` module declarations may carry KDoc describing\nthe contract — that's documentation for consumers, not narration.\n\nNever add:\n\n- **narration** of trivial code\n- **conversational / temporal residue**\n- **process / plan references**\n\n```kotlin\ncount++ // increment the counter -> narration of trivial code\nval user = repo.load() // fixes the bug from the previous task -> temporal residue\nval state = flow // changed from LiveData -> temporal residue\ncache.clear() // step 3 of the plan -> process / plan reference\nretryCount = 3 // per the Asana task -> process / plan reference\n```\n\nWhen reviewing a diff, flag any added comment that doesn't follow these rules.\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.claude-plugin/plugin.json)",".cursorrules (android-jetpack-compose-cursorrules-prompt-file.mdc)":"---\ndescription: \"Cursor rules for Android development with Jetpack Compose integration.\"\nglobs: **/*\nalwaysApply: false\n---\n// Android Jetpack Compose .cursorrules\n\n// Flexibility Notice\n\n// Note: This is a recommended project structure, but be flexible and adapt to existing project structures.\n// Do not enforce these structural patterns if the project follows a different organization.\n// Focus on maintaining consistency with the existing project architecture while applying Jetpack Compose best practices.\n\n// Project Architecture and Best Practices\n\nconst androidJetpackComposeBestPractices = [\n    \"Adapt to existing project architecture while maintaining clean code principles\",\n    \"Follow Material Design 3 guidelines and components\",\n    \"Implement clean architecture with domain, data, and presentation layers\",\n    \"Use Kotlin coroutines and Flow for asynchronous operations\",\n    \"Implement dependency injection using Hilt\",\n    \"Follow unidirectional data flow with ViewModel and UI State\",\n    \"Use Compose navigation for screen management\",\n    \"Implement proper state hoisting and composition\",\n];\n\n// Folder Structure\n\n// Note: This is a reference structure. Adapt to the project's existing organization\n\nconst projectStructure = `\napp/\n  src/\n    main/\n      java/com/package/\n        data/\n          repository/\n          datasource/\n          models/\n        domain/\n          usecases/\n          models/\n          repository/\n        presentation/\n          screens/\n          components/\n          theme/\n          viewmodels/\n        di/\n        utils/\n      res/\n        values/\n        drawable/\n        mipmap/\n    test/\n    androidTest/\n`;\n\n// Compose UI Guidelines\n\nconst composeGuidelines = `\n1. Use remember and derivedStateOf appropriately\n2. Implement proper recomposition optimization\n3. Use proper Compose modifiers ordering\n4. Follow composable function naming conventions\n5. Implement proper preview annotations\n6. Use proper state management with MutableState\n7. Implement proper error handling and loading states\n8. Use proper theming with MaterialTheme\n9. Follow accessibility guidelines\n10. Implement proper animation patterns\n`;\n\n// Testing Guidelines\n\nconst testingGuidelines = `\n1. Write unit tests for ViewModels and UseCases\n2. Implement UI tests using Compose testing framework\n3. Use fake repositories for testing\n4. Implement proper test coverage\n5. Use proper testing coroutine dispatchers\n`;\n\n// Performance Guidelines\n\nconst performanceGuidelines = `\n1. Minimize recomposition using proper keys\n2. Use proper lazy loading with LazyColumn and LazyRow\n3. Implement efficient image loading\n4. Use proper state management to prevent unnecessary updates\n5. Follow proper lifecycle awareness\n6. Implement proper memory management\n7. Use proper background processing\n`;\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/duckduckgo/Android/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md — DuckDuckGo Android Browser\n\nDuckDuckGo Android is a privacy-focused browser built as a large multi-module Gradle project,\nproviding built-in search, tracker blocking, HTTPS enforcement and other privacy features.\n\n**Versions** (SDK levels, Kotlin, Gradle, libraries) live in the build files — don't restate them here:\n`min_sdk` / `target_sdk` / `compile_sdk` in `build.gradle`, `version.kotlin` in `versions.properties`,\nand the Gradle version in `gradle/wrapper/gradle-wrapper.properties`.\n**Build:** AGP via refreshVersions. DI is **Metro** (KSP generators in `:codegen-ksp`; see `.claude/docs/architecture.md`).\n**Toolchain:** Kotlin JVM target 17; building requires **JDK 21** (Metro compiler plugin).\n\nNotable libraries: Room, Retrofit/OkHttp/Moshi, Coroutines, Jetpack Compose (selective), WorkManager,\n`logcat` (Square), KSP for annotation processing. Versions are in `versions.properties` and the module\n`build.gradle` files.\n\n---\n\n## Privacy invariants for anything leaving the device\n\nThis is a privacy browser; these hold for every outbound value — pixels, wide events, logs, crash\nreports, debug output — not just telemetry you are deliberately designing.\n\n- **No PII.** Never emails, names, account IDs, usernames or phone numbers, in a name or a value.\n- **No URLs, domains or page titles.** Breakage reports are the one controlled exception, with explicit\n  user consent.\n- **No correlation IDs.** No session IDs, GUIDs or exact timestamps — anything that links events to one\n  user session.\n- **Bucket numeric values.** Exact durations, byte counts and item counts fingerprint users; send ranges.\n- **Bounded enums over free-form strings.** High-cardinality unbounded strings are both a privacy risk\n  and unanalysable.\n\nAdding or changing a pixel or the pixel registry also requires privacy triage — see\n`.claude/docs/pixels.md`.\n\n---\n\n## Read these when the situation applies\n\nThese files are not in context. Read the whole file before doing the work it covers — don't rely on\nwhat you remember of it.\n\n| Read | When |\n|---|---|\n| `.claude/docs/architecture.md` | **planning or implementing** any new code, refactoring, or module changes — `-api`/`-impl` structure, DI scopes, navigation, coroutine job patterns |\n| `.claude/docs/android-design-system.md` | **planning or implementing** any UI — which ADS component to use, colors, spacing; raw Android/Material widgets are lint-blocked |\n| `.claude/docs/contributions.md` | **planning** a change that touches a `-api` surface or spans multiple modules — it needs an approved API Proposal and/or Tech Design, and that has to be raised before implementation, not at PR time. Also read it when naming a branch, writing a commit, or opening a PR |\n| `.claude/docs/lateinit-hazards.md` | writing or reviewing any `lateinit var`, especially `@Inject lateinit var` in a View |\n| `.claude/docs/plugin-system.md` | declaring a plugin point or contributing a plugin (`PluginPoint` / `ActivePluginPoint`) |\n| `.claude/docs/native-input.md` | **changing** the native input (`NativeInputModeWidget`, its plugins and footers, `NativeInputManager`, the contextual sheet or the edit screen) — adding a control, state-store rules, host gotchas, and the refactor still in flight |\n| `.claude/docs/pixels.md` | adding or changing pixel telemetry — including whether a pixel or a wide event is the right instrument |\n| `.claude/docs/di-scopes.md` | an injection fails at runtime (\"Could not find the injector\"), or you're deciding which scope to pass to `@InjectWith` — has the component/subcomponent diagram and the `injectorFactoryMap` lookups |\n| `.claude/docs/navigation.md` | adding a screen or navigating to one — `ActivityParams`, `@ContributeToActivityStarter`, deeplinks, and which `GlobalActivityStarter` overload to use |\n| `.claude/docs/url-classification.md` | routing typed input to navigation vs search — use `QueryUrlPredictor`, not `UriString.isWebUrl()` |\n| `.claude/docs/icons.md` | the change needs an icon the project doesn't have yet — it must be fetched from the internal Icons repository, never invented |\n| `.claude/docs/translations.md` | adding or changing any user-facing string — `donottranslate.xml` vs `strings-<module>.xml`, placeholder/`instruction` rules, how to change or remove already-translated copy |\n\n---\n\n## Build & Test Commands\n\n```bash\n# Unit tests (all modules)\n./gradlew jvm_tests\n\n# Unit tests for a single module\n./gradlew :my-feature-impl:testDebugUnitTest\n\n# Code quality (spotless + lint + unit tests)\n./gradlew jvm_checks\n\n# Lint only\n./gradlew lint_check\n\n# Code formatting check / fix\n./gradlew spotlessCheck\n./gradlew spotlessApply\n\n# Install app\n./gradlew installInternalRelease    # internal build (more testing features)\n./gradlew installPlayRelease        # play store build\n```\n\n`jvm_tests` and `jvm_checks` resolve to `testPlayDebugUnitTest` in `:app` and `testDebugUnitTest` in\nlibrary modules. To run a single test class, use `--tests`:\n\n```bash\n./gradlew :my-feature-impl:testDebugUnitTest --tests \"com.duckduckgo.my.feature.RealFooTest\"\n```\n\n### Build Variants\n\n| Dimension | Flavors |\n|---|---|\n| store | `internal`, `fdroid`, `play` |\n| Build types | `debug`, `release`, `upload` |\n\n### Proprietary Fonts\n\nThe app uses a proprietary DuckSans font from a private GitHub Packages repository. The build\nconditionally swaps between the proprietary `ddg-proprietary-fonts` AAR and a local `:fonts` fallback\nmodule (empty `<font-family/>` stubs) based on credential availability. See `build.gradle` for the\ncredential detection logic and `android-design-system/fonts/readme.md` for details.\n\n---\n\n## Code Formatting\n\n- **Spotless** with ktlint for Kotlin; Google Java Format in AOSP style for Java\n- Max line length: 150 characters\n- Ratchet from `origin/develop` — only changed code is enforced\n\n---\n\n## Code Comments\n\nComments explain the **why** (intent, assumptions, non-obvious decisions), not the **what** the code\nalready shows.\n\nDefault to no comment: prefer self-documenting code (clear names, small functions), and add one only\nwhere code alone can't carry the reasoning, and only if it still answers *\"why was this done this\nway?\"* for someone reading it two years from now. `-api` module declarations may carry KDoc describing\nthe contract — that's documentation for consumers, not narration.\n\nNever add:\n\n- **narration** of trivial code\n- **conversational / temporal residue**\n- **process / plan references**\n\n```kotlin\ncount++ // increment the counter -> narration of trivial code\nval user = repo.load() // fixes the bug from the previous task -> temporal residue\nval state = flow // changed from LiveData -> temporal residue\ncache.clear() // step 3 of the plan -> process / plan reference\nretryCount = 3 // per the Asana task -> process / plan reference\n```\n\nWhen reviewing a diff, flag any added comment that doesn't follow these rules.\n","isInternal":false,"tokens":1648,"sizeBytes":6915},{"name":"marketplace.json","path":".claude-plugin/marketplace.json","rawUrl":"https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.claude-plugin/marketplace.json","title":"Claude Plugin Marketplace Catalog","category":"marketplace","format":"json","content":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.claude-plugin/marketplace.json)","tokens":300,"sizeBytes":197},{"name":"plugin.json","path":".claude-plugin/plugin.json","rawUrl":"https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.claude-plugin/plugin.json","title":"claude-plugin Plugin Manifest","category":"plugin-manifest","format":"json","content":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.claude-plugin/plugin.json)","tokens":300,"sizeBytes":183},{"name":"mcp.json","path":".cursor/mcp.json","rawUrl":"https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.cursor/mcp.json","title":"Model Context Protocol (MCP) Configuration","category":"mcp-config","format":"json","content":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.cursor/mcp.json)","tokens":300,"sizeBytes":176},{"name":".cursorrules","path":".cursorrules (android-jetpack-compose-cursorrules-prompt-file.mdc)","rawUrl":"https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/main/rules/android-jetpack-compose-cursorrules-prompt-file.mdc","title":"Awesome Cursorrules: android jetpack compose","category":"cursor-rule","format":"markdown","content":"---\ndescription: \"Cursor rules for Android development with Jetpack Compose integration.\"\nglobs: **/*\nalwaysApply: false\n---\n// Android Jetpack Compose .cursorrules\n\n// Flexibility Notice\n\n// Note: This is a recommended project structure, but be flexible and adapt to existing project structures.\n// Do not enforce these structural patterns if the project follows a different organization.\n// Focus on maintaining consistency with the existing project architecture while applying Jetpack Compose best practices.\n\n// Project Architecture and Best Practices\n\nconst androidJetpackComposeBestPractices = [\n    \"Adapt to existing project architecture while maintaining clean code principles\",\n    \"Follow Material Design 3 guidelines and components\",\n    \"Implement clean architecture with domain, data, and presentation layers\",\n    \"Use Kotlin coroutines and Flow for asynchronous operations\",\n    \"Implement dependency injection using Hilt\",\n    \"Follow unidirectional data flow with ViewModel and UI State\",\n    \"Use Compose navigation for screen management\",\n    \"Implement proper state hoisting and composition\",\n];\n\n// Folder Structure\n\n// Note: This is a reference structure. Adapt to the project's existing organization\n\nconst projectStructure = `\napp/\n  src/\n    main/\n      java/com/package/\n        data/\n          repository/\n          datasource/\n          models/\n        domain/\n          usecases/\n          models/\n          repository/\n        presentation/\n          screens/\n          components/\n          theme/\n          viewmodels/\n        di/\n        utils/\n      res/\n        values/\n        drawable/\n        mipmap/\n    test/\n    androidTest/\n`;\n\n// Compose UI Guidelines\n\nconst composeGuidelines = `\n1. Use remember and derivedStateOf appropriately\n2. Implement proper recomposition optimization\n3. Use proper Compose modifiers ordering\n4. Follow composable function naming conventions\n5. Implement proper preview annotations\n6. Use proper state management with MutableState\n7. Implement proper error handling and loading states\n8. Use proper theming with MaterialTheme\n9. Follow accessibility guidelines\n10. Implement proper animation patterns\n`;\n\n// Testing Guidelines\n\nconst testingGuidelines = `\n1. Write unit tests for ViewModels and UseCases\n2. Implement UI tests using Compose testing framework\n3. Use fake repositories for testing\n4. Implement proper test coverage\n5. Use proper testing coroutine dispatchers\n`;\n\n// Performance Guidelines\n\nconst performanceGuidelines = `\n1. Minimize recomposition using proper keys\n2. Use proper lazy loading with LazyColumn and LazyRow\n3. Implement efficient image loading\n4. Use proper state management to prevent unnecessary updates\n5. Follow proper lifecycle awareness\n6. Implement proper memory management\n7. Use proper background processing\n`;\n","tokens":545,"sizeBytes":2817}],"systemPromptSnippet":"<yakaai_skills repo=\"duckduckgo/Android\">\n<!-- File: AGENTS.md (Tokens: ~1648 | Category: root-instruction) -->\n# AGENTS.md — DuckDuckGo Android Browser\n\nDuckDuckGo Android is a privacy-focused browser built as a large multi-module Gradle project,\nproviding built-in search, tracker blocking, HTTPS enforcement and other privacy features.\n\n**Versions** (SDK levels, Kotlin, Gradle, libraries) live in the build files — don't restate them here:\n`min_sdk` / `target_sdk` / `compile_sdk` in `build.gradle`, `version.kotlin` in `versions.properties`,\nand the Gradle version in `gradle/wrapper/gradle-wrapper.properties`.\n**Build:** AGP via refreshVersions. DI is **Metro** (KSP generators in `:codegen-ksp`; see `.claude/docs/architecture.md`).\n**Toolchain:** Kotlin JVM target 17; building requires **JDK 21** (Metro compiler plugin).\n\nNotable libraries: Room, Retrofit/OkHttp/Moshi, Coroutines, Jetpack Compose (selective), WorkManager,\n`logcat` (Square), KSP for annotation processing. Versions are in `versions.properties` and the module\n`build.gradle` files.\n\n---\n\n## Privacy invariants for anything leaving the device\n\nThis is a privacy browser; these hold for every outbound value — pixels, wide events, logs, crash\nreports, debug output — not just telemetry you are deliberately designing.\n\n- **No PII.** Never emails, names, account IDs, usernames or phone numbers, in a name or a value.\n- **No URLs, domains or page titles.** Breakage reports are the one controlled exception, with explicit\n  user consent.\n- **No correlation IDs.** No session IDs, GUIDs or exact timestamps — anything that links events to one\n  user session.\n- **Bucket numeric values.** Exact durations, byte counts and item counts fingerprint users; send ranges.\n- **Bounded enums over free-form strings.** High-cardinality unbounded strings are both a privacy risk\n  and unanalysable.\n\nAdding or changing a pixel or the pixel registry also requires privacy triage — see\n`.claude/docs/pixels.md`.\n\n---\n\n## Read these when the situation applies\n\nThese files are not in context. Read the whole file before doing the work it covers — don't rely on\nwhat you remember of it.\n\n| Read | When |\n|---|---|\n| `.claude/docs/architecture.md` | **planning or implementing** any new code, refactoring, or module changes — `-api`/`-impl` structure, DI scopes, navigation, coroutine job patterns |\n| `.claude/docs/android-design-system.md` | **planning or implementing** any UI — which ADS component to use, colors, spacing; raw Android/Material widgets are lint-blocked |\n| `.claude/docs/contributions.md` | **planning** a change that touches a `-api` surface or spans multiple modules — it needs an approved API Proposal and/or Tech Design, and that has to be raised before implementation, not at PR time. Also read it when naming a branch, writing a commit, or opening a PR |\n| `.claude/docs/lateinit-hazards.md` | writing or reviewing any `lateinit var`, especially `@Inject lateinit var` in a View |\n| `.claude/docs/plugin-system.md` | declaring a plugin point or contributing a plugin (`PluginPoint` / `ActivePluginPoint`) |\n| `.claude/docs/native-input.md` | **changing** the native input (`NativeInputModeWidget`, its plugins and footers, `NativeInputManager`, the contextual sheet or the edit screen) — adding a control, state-store rules, host gotchas, and the refactor still in flight |\n| `.claude/docs/pixels.md` | adding or changing pixel telemetry — including whether a pixel or a wide event is the right instrument |\n| `.claude/docs/di-scopes.md` | an injection fails at runtime (\"Could not find the injector\"), or you're deciding which scope to pass to `@InjectWith` — has the component/subcomponent diagram and the `injectorFactoryMap` lookups |\n| `.claude/docs/navigation.md` | adding a screen or navigating to one — `ActivityParams`, `@ContributeToActivityStarter`, deeplinks, and which `GlobalActivityStarter` overload to use |\n| `.claude/docs/url-classification.md` | routing typed input to navigation vs search — use `QueryUrlPredictor`, not `UriString.isWebUrl()` |\n| `.claude/docs/icons.md` | the change needs an icon the project doesn't have yet — it must be fetched from the internal Icons repository, never invented |\n| `.claude/docs/translations.md` | adding or changing any user-facing string — `donottranslate.xml` vs `strings-<module>.xml`, placeholder/`instruction` rules, how to change or remove already-translated copy |\n\n---\n\n## Build & Test Commands\n\n```bash\n# Unit tests (all modules)\n./gradlew jvm_tests\n\n# Unit tests for a single module\n./gradlew :my-feature-impl:testDebugUnitTest\n\n# Code quality (spotless + lint + unit tests)\n./gradlew jvm_checks\n\n# Lint only\n./gradlew lint_check\n\n# Code formatting check / fix\n./gradlew spotlessCheck\n./gradlew spotlessApply\n\n# Install app\n./gradlew installInternalRelease    # internal build (more testing features)\n./gradlew installPlayRelease        # play store build\n```\n\n`jvm_tests` and `jvm_checks` resolve to `testPlayDebugUnitTest` in `:app` and `testDebugUnitTest` in\nlibrary modules. To run a single test class, use `--tests`:\n\n```bash\n./gradlew :my-feature-impl:testDebugUnitTest --tests \"com.duckduckgo.my.feature.RealFooTest\"\n```\n\n### Build Variants\n\n| Dimension | Flavors |\n|---|---|\n| store | `internal`, `fdroid`, `play` |\n| Build types | `debug`, `release`, `upload` |\n\n### Proprietary Fonts\n\nThe app uses a proprietary DuckSans font from a private GitHub Packages repository. The build\nconditionally swaps between the proprietary `ddg-proprietary-fonts` AAR and a local `:fonts` fallback\nmodule (empty `<font-family/>` stubs) based on credential availability. See `build.gradle` for the\ncredential detection logic and `android-design-system/fonts/readme.md` for details.\n\n---\n\n## Code Formatting\n\n- **Spotless** with ktlint for Kotlin; Google Java Format in AOSP style for Java\n- Max line length: 150 characters\n- Ratchet from `origin/develop` — only changed code is enforced\n\n---\n\n## Code Comments\n\nComments explain the **why** (intent, assumptions, non-obvious decisions), not the **what** the code\nalready shows.\n\nDefault to no comment: prefer self-documenting code (clear names, small functions), and add one only\nwhere code alone can't carry the reasoning, and only if it still answers *\"why was this done this\nway?\"* for someone reading it two years from now. `-api` module declarations may carry KDoc describing\nthe contract — that's documentation for consumers, not narration.\n\nNever add:\n\n- **narration** of trivial code\n- **conversational / temporal residue**\n- **process / plan references**\n\n```kotlin\ncount++ // increment the counter -> narration of trivial code\nval user = repo.load() // fixes the bug from the previous task -> temporal residue\nval state = flow // changed from LiveData -> temporal residue\ncache.clear() // step 3 of the plan -> process / plan reference\nretryCount = 3 // per the Asana task -> process / plan reference\n```\n\nWhen reviewing a diff, flag any added comment that doesn't follow these rules.\n\n<!-- File: .claude-plugin/marketplace.json (Tokens: ~300 | Category: marketplace) -->\n# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.claude-plugin/marketplace.json)\n\n<!-- File: .claude-plugin/plugin.json (Tokens: ~300 | Category: plugin-manifest) -->\n# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.claude-plugin/plugin.json)\n\n<!-- File: .cursor/mcp.json (Tokens: ~300 | Category: mcp-config) -->\n# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/duckduckgo/Android/HEAD/.cursor/mcp.json)\n\n<!-- File: .cursorrules (android-jetpack-compose-cursorrules-prompt-file.mdc) (Tokens: ~545 | Category: cursor-rule) -->\n---\ndescription: \"Cursor rules for Android development with Jetpack Compose integration.\"\nglobs: **/*\nalwaysApply: false\n---\n// Android Jetpack Compose .cursorrules\n\n// Flexibility Notice\n\n// Note: This is a recommended project structure, but be flexible and adapt to existing project structures.\n// Do not enforce these structural patterns if the project follows a different organization.\n// Focus on maintaining consistency with the existing project architecture while applying Jetpack Compose best practices.\n\n// Project Architecture and Best Practices\n\nconst androidJetpackComposeBestPractices = [\n    \"Adapt to existing project architecture while maintaining clean code principles\",\n    \"Follow Material Design 3 guidelines and components\",\n    \"Implement clean architecture with domain, data, and presentation layers\",\n    \"Use Kotlin coroutines and Flow for asynchronous operations\",\n    \"Implement dependency injection using Hilt\",\n    \"Follow unidirectional data flow with ViewModel and UI State\",\n    \"Use Compose navigation for screen management\",\n    \"Implement proper state hoisting and composition\",\n];\n\n// Folder Structure\n\n// Note: This is a reference structure. Adapt to the project's existing organization\n\nconst projectStructure = `\napp/\n  src/\n    main/\n      java/com/package/\n        data/\n          repository/\n          datasource/\n          models/\n        domain/\n          usecases/\n          models/\n          repository/\n        presentation/\n          screens/\n          components/\n          theme/\n          viewmodels/\n        di/\n        utils/\n      res/\n        values/\n        drawable/\n        mipmap/\n    test/\n    androidTest/\n`;\n\n// Compose UI Guidelines\n\nconst composeGuidelines = `\n1. Use remember and derivedStateOf appropriately\n2. Implement proper recomposition optimization\n3. Use proper Compose modifiers ordering\n4. Follow composable function naming conventions\n5. Implement proper preview annotations\n6. Use proper state management with MutableState\n7. Implement proper error handling and loading states\n8. Use proper theming with MaterialTheme\n9. Follow accessibility guidelines\n10. Implement proper animation patterns\n`;\n\n// Testing Guidelines\n\nconst testingGuidelines = `\n1. Write unit tests for ViewModels and UseCases\n2. Implement UI tests using Compose testing framework\n3. Use fake repositories for testing\n4. Implement proper test coverage\n5. Use proper testing coroutine dispatchers\n`;\n\n// Performance Guidelines\n\nconst performanceGuidelines = `\n1. Minimize recomposition using proper keys\n2. Use proper lazy loading with LazyColumn and LazyRow\n3. Implement efficient image loading\n4. Use proper state management to prevent unnecessary updates\n5. Follow proper lifecycle awareness\n6. Implement proper memory management\n7. Use proper background processing\n`;\n</yakaai_skills>"}