

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# Injected Features23JavaScript features injected into web pages or running in DOM environments of DuckDuckGo browsers. Features extend `ContentFeature` and `ConfigFeature` and integrate with remote configuration for per-site enable/disable.45**See also:**6- `docs/coding-guidelines.md` for code style, patterns, and examples7- `docs/css-decision-guide.md` for when to use C-S-S vs native code8- [privacy-configuration experiments guide](https://github.com/duckduckgo/privacy-configuration/blob/main/.cursor/rules/content-scope-experiments.mdc) for A/B testing features910## Structure1112```13src/features/<name>.js # Feature implementation (extends ContentFeature)14src/features.js # Feature registry (baseFeatures + otherFeatures arrays)15entry-points/<platform>.js # Platform-specific bundles16integration-test/ # Playwright integration tests17unit-test/ # Jasmine unit tests18```1920**Adding a new feature:** Add to `baseFeatures` or `otherFeatures` in `src/features.js`, then add to relevant platform arrays in `platformSupport`. Build the project after adding a new feature in `src/features/` to keep types up-to-date (`npm run build`).2122**Strict TypeScript:** All new feature files must be added to the `CORE_FILES` set in `scripts/check-strict-core.js`. This enforces full TypeScript strict mode (`strict: true`, `noUncheckedIndexedAccess`) on the file. Run `npm run tsc-strict-core` from the repo root to verify. Existing files in the set must not regress.2324## TypeScript2526JSDoc types in JavaScript files. Import types via `@typedef`:2728```javascript29/** @typedef {import('../types/feature.js').SettingType} SettingType */30```3132## Testing3334Run from `injected/` directory:3536| Command | Purpose |37|---------|---------|38| `npm run test-unit` | Jasmine unit tests |39| `npm run test-int` | Playwright integration tests |40| `npm run build` | Build all platform bundles |4142Integration tests use test pages in `integration-test/test-pages/`.4344## Linting4546After making code changes, **always run** `npm run lint-fix` (from repo root) and incorporate any auto-fixes before returning results.4748## Key Patterns4950- **Event listeners**: Use `handleEvent` pattern or stored references (avoid `.bind(this)`)51- **API existence**: Check `typeof API === 'function'` before wrapping52- **DOM timing**: Check `document.readyState` before accessing DOM53- **Error types**: Match native error signatures in API shims5455See `docs/coding-guidelines.md` for DDGProxy, captured globals, retry utilities, and other patterns.5657## Platform Considerations5859Features are bundled per-platform in `entry-points/`:60- `apple.js` - iOS/macOS61- `android.js` - Android62- `windows.js` - Windows63- `extension-mv3.js` - Browser extension6465Platform-specific features: `navigatorInterface`, `windowsPermissionUsage`, `messageBridge`, `favicon`, `breakageReporting`, `webInterferenceDetection`, `webDetection`, `webEvents` (see `utils.js` `platformSpecificFeatures`).6667## Messaging Constraints6869- **Never include `nativeData` as a field in any message sent to the client.** The `nativeData` field is reserved for native platform use — native implementations inject a `nativeData` field into incoming messages, and `nativeData` is reserved for that layer. When constructing `notify()` or `request()` params, only pass explicitly defined fields (destructure rather than spread).7071## Notes7273- When running Playwright commands, use `--reporter list` to prevent hanging74- Features can be enabled/disabled per-site via remote config75- Add debug flags with `this.addDebugFlag()` for breakage reports7677## “internal” / “preview” conditional config7879The injected config system supports `internal` and `preview` keys inside conditional blocks (see `ConfigFeature` in `injected/src/config-feature.js`). These values come from `userPreferences.platform.internal` / `userPreferences.platform.preview` and are not inferred automatically.80
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| duckduckgo/content-scope-scriptstypes-generator/AGENTS.md · 70 | AGENTS.md | testarchtypesdo-not | 73/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-broker-protection-actions.mdc · 70 | Cursor rules | buildteststyletypes+4 | 93/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-broker-protection-rest.mdc · 70 | Cursor rules | teststyletypesgit+3 | 89/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-click-to-load.mdc · 70 | Cursor rules | teststyletypesgit+2 | 89/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-detectors.mdc · 70 | Cursor rules | teststyletypesgit+3 | 89/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-duckplayer-native.mdc · 70 | Cursor rules | teststyletypesgit+3 | 89/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-duckplayer.mdc · 70 | Cursor rules | setupteststyletypes+4 | 89/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-fingerprinting.mdc · 70 | Cursor rules | teststyletypesgit+3 | 89/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-message-bridge.mdc · 70 | Cursor rules | teststyletypesgit+3 | 89/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-standalone-features-a.mdc · 70 | Cursor rules | teststyletypesgit+4 | 89/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-standalone-features-b.mdc · 70 | Cursor rules | teststyletypesgit+3 | 89/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-standalone-features-c.mdc · 70 | Cursor rules | teststyletypesgit+4 | 89/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-web-compat-and-telemetry.mdc · 70 | Cursor rules | teststyletypesgit+3 | 89/100 | 14 days ago | |
| duckduckgo/content-scope-scripts.cursor/rules/strict-zero-errors-batch.mdc · 70 | Cursor rules | testtypesgitdo-not+1 | 81/100 | 14 days ago | |
| duckduckgo/content-scope-scriptsAGENTS.md · 70 | AGENTS.md | buildtestlint-formatstyle+5 | 83/100 | 14 days ago | |
| duckduckgo/content-scope-scriptsmessaging/AGENTS.md · 70 | AGENTS.md | testarchtesting-strategyapi | 66/100 | 14 days ago | |
| duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70 | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 201k | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| aaif-goose/gooseAGENTS.md · 53k | AGENTS.md | setupbuildtestlint-format+7 | 100/100 | 8 days ago | |
| duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70 | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| deepseek-ai/deepseek-harnessnative/landlock-run/AGENTS.md · 104k | AGENTS.md | setupteststylearch+3 | 100/100 | today | |
| code-yeongyu/oh-my-openagentpackages/web/AGENTS.md · 68k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 13 days ago | |
| TryGhost/Ghoste2e/AGENTS.md · 55k | AGENTS.md | setupteststylearch+2 | 100/100 | today | |
| mui/material-uiAGENTS.md · 99k | AGENTS.md | setupbuildtestlint-format+9 | 100/100 | 14 days ago | |
| elastic/elasticsearchx-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/AGENTS.md · 78k | AGENTS.md | buildtestlint-formatstyle+2 | 100/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/duckduckgo-content-scope-scripts-injected-agents)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.