Two files, one repository
duckduckgo/content-scope-scripts ships 2 formats across 18 indexed files. The question worth asking is whether the second one says anything the first does not.
CompareAGENTS.md ↔ Cursor rules
| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 0 | 13 | 14 | 0% |
| Commands | 5 | 7 | 2 | 36% |
| Section tags | 5 | 4 | 2 | 45% |
What each file covers
Sections
0 shared · 13 only in A · 14 only in B- − Content Scope Scripts (C-S-S)
- − Workspaces
- − `injected/` - Browser Privacy Features
- − `special-pages/` - Embedded Browser Pages
- − `messaging/` - Web-Native Communication
- − `types-generator/` - Schema to TypeScript
- − Commands
- − Coding Standards
- − Strict TypeScript
- − Debugging
- − Notes
- − Local dev quick wins (common pain points)
- − Cursor Cloud specific instructions
- + Strict TypeScript: DuckPlayer Native
- + Task
- + Branch
- + Files (20 errors total)
- + `injected/src/features/duck-player-native.js` (4 errors)
- + `injected/src/features/duckplayer-native/custom-error/custom-error.js` (2 errors)
- + `injected/src/features/duckplayer-native/messages.js` (3 errors)
- + `injected/src/features/duckplayer-native/overlays/thumbnail-overlay.js` (3 errors)
- + `injected/src/features/duckplayer-native/sub-features/duck-player-native-no-cookie.js` (1 error)
- + `injected/src/features/duckplayer-native/sub-features/duck-player-native-youtube.js` (1 error)
- + `injected/src/features/duckplayer-native/youtube-errors.js` (6 errors)
- + Fix Patterns
- + Workflow
- + Constraints
Commands
5 shared · 7 only in A · 2 only in B- − npm run build
- − npm run test-int
- − npm run serve
- − npm run serve-special-pages
- − npm run watch -- --page=<page>
- − npm link
- − npm run test-int-x
- + git checkout main && git pull origin main && git checkout -b cursor/strict/duckplayer-native
- + git push -u origin cursor/strict/duckplayer-native
- npm run test-unit
- npm run lint
- npm run lint-fix
- npm run tsc-strict-core
- npm ci
Section tags
5 shared · 4 only in A · 2 only in B- − build
- − lint-format
- − database
- − deployment
- + do-not
- + docs
- test
- code-style
- types
- git-pr
- agent-behaviour
Line diff
duckduckgo/content-scope-scripts · AGENTS.md
@@ −1 @@
1# Content Scope Scripts (C-S-S)
2
3Shared JavaScript projects powering privacy features and special pages in DuckDuckGo's native apps (macOS, Windows, iOS, Android).
4
5## Workspaces
6
7This is an npm workspace monorepo with four sub-projects:
8
9### `injected/` - Browser Privacy Features
10
11JavaScript features injected into web pages for privacy protections. Features extend `ConfigFeature` and integrate with remote configuration for per-site enable/disable.
12
13**Features** (in `injected/src/features/`):
14- `api-manipulation` - API behavior modifications
15- `autofill-import` - Credential import support
16- `breakage-reporting` - Site breakage reports
17- `broker-protection` - Data broker removal automation
18- `click-to-load` - Social embed blocking
19- `cookie` - Cookie management
20- `duck-player` / `duck-player-native` - YouTube privacy player
21- `element-hiding` - Hide page elements
22- `exception-handler` - Error handling
23- `favicon` - Favicon privacy
24- `fingerprinting-*` - Audio, battery, canvas, hardware, screen, storage fingerprint protection
25- `google-rejected` - Google rejection handling
26- `gpc` - Global Privacy Control
27- `harmful-apis` - Dangerous API restrictions
28- `message-bridge` - Page↔content script messaging
29- `navigator-interface` - Navigator API modifications
30- `performance-metrics` - Performance tracking
31- `referrer` - Referrer protection
32- `web-compat` - Site compatibility fixes
33- `web-interference-detection` / `web-telemetry` - Monitoring
34
35**Docs:** `injected/docs/README.md` (index to all docs)
36
37### `special-pages/` - Embedded Browser Pages
38
39Preact-based HTML/CSS/JS applications embedded in browsers. Each page lives in `special-pages/pages/<name>/`.
40
41**Pages:**
42- `duckplayer` - YouTube privacy player UI
43- `errorpage` - Browser error pages
44- `example` - Template for new pages
45- `history` - Browsing history viewer
46- `new-tab` - New Tab Page
47- `onboarding` - First-run experience
48- `release-notes` - Browser release notes
49- `special-error` - SSL/certificate error pages
50
51**Docs:** `special-pages/README.md`, plus `readme.md` in each page directory
52
53### `messaging/` - Web-Native Communication
54
55Abstraction layer for web↔native messaging: `notify` (fire-and-forget), `request` (async response), `subscribe` (push updates).
56
57**Docs:** `messaging/docs/messaging.md`
58
59### `types-generator/` - Schema to TypeScript
60
61Generates TypeScript types from JSON Schema files. Used by other workspaces.
62
63## Commands
64
65Run from root. Use `nvm use` to set the correct Node version.
66
67| Command | Purpose |
68|---------|---------|
69| `npm run build` | Build all workspaces |
70| `npm run test-unit` | Unit tests (all workspaces) |
71| `npm run test-int` | Integration tests (Playwright) |
72| `npm run lint` | ESLint + TypeScript + Prettier |
73| `npm run lint-fix` | Auto-fix lint issues |
74| `npm run serve` | Serve injected test pages (port 3220) |
75| `npm run serve-special-pages` | Serve special pages (port 3221) |
76
77## Coding Standards
78
79Follow the error handling guidelines in [`guides/error-handling.md`](guides/error-handling.md). Key rules:
80- Errors are for **exceptional conditions** (invariant violations, unreachable code), not control flow
81- Never leave promises unhandled — use `.catch()` or `try/catch` with `await`
82- Return `null`/sentinel values for expected missing data instead of throwing
83
84### Strict TypeScript
85
86All **new** source files under `injected/src/` must be added to the `CORE_FILES` set in `scripts/check-strict-core.js`. This enforces TypeScript strict mode (`strict: true`, `noUncheckedIndexedAccess`). Run `npm run tsc-strict-core` to verify. Do not remove existing entries from the set.
87
88## Debugging
89
90See [`guides/debugging.md`](guides/debugging.md) for debugging resources including script integrity validation, feature triage checklist, and platform-specific troubleshooting.
91
92## Notes
93
94- When running Playwright commands, use `--reporter list` to prevent the Shell tool from hanging
95- Use `.github/pull_request_template.md` when creating a pull request.
96
97## Local dev quick wins (common pain points)
98
99- **Special Pages CSS local dev**: use `npm run serve-special-pages` (repo root) + `npm run watch -- --page=<page>` (inside `special-pages/`) for hot CSS reload (usually `http://localhost:8000/`). The `build/` output does **not** auto-update in watch mode.
100- **Release workflow**: releases are created from GitHub Actions (see `CONTRIBUTING.md` → “Release Process”). For most iteration, prefer Netlify preview URLs or `npm link` into native apps; only cut a release when you need native consumption via the `releases` branch artifacts.
101
102## Cursor Cloud specific instructions
103
104- Node 22 and npm are pre-installed. Playwright browsers + system deps are pre-installed. Just run `npm ci` to refresh dependencies.
105- `npm run serve-special-pages` actually serves on **port 3210** (not 3221 as the Commands table above states). The injected test pages serve on port 3220 as documented.
106- Integration tests for injected workspace may show 2 flaky iOS mobile drawer timeouts (`duckplayer-mobile-drawer.spec.js`); these are pre-existing timing issues, not environment problems.
107- No Docker, databases, or external services are needed. All tests are self-contained with local HTTP servers and mocked native messaging.
108- On headless Linux, `xvfb` is pre-installed. The injected workspace provides `npm run test-int-x` which wraps Playwright with `xvfb-run`, but standard `npm run test-int` also works in this environment.
109
duckduckgo/content-scope-scripts · .cursor/rules/strict-duckplayer-native.mdc
@@ +1 @@
1---
2description: "Subagent task: Fix strict TypeScript errors in duckplayer-native files and add to CORE_FILES"
3globs:
4 - "scripts/check-strict-core.js"
5 - "injected/src/features/duck-player-native.js"
6 - "injected/src/features/duckplayer-native/custom-error/custom-error.js"
7 - "injected/src/features/duckplayer-native/messages.js"
8 - "injected/src/features/duckplayer-native/overlays/thumbnail-overlay.js"
9 - "injected/src/features/duckplayer-native/sub-features/duck-player-native-no-cookie.js"
10 - "injected/src/features/duckplayer-native/sub-features/duck-player-native-youtube.js"
11 - "injected/src/features/duckplayer-native/youtube-errors.js"
12---
13
14# Strict TypeScript: DuckPlayer Native
15
16## Task
17
18Fix all strict-mode TypeScript errors in 7 duckplayer-native files and add them to `CORE_FILES`.
19
20## Branch
21
22```
23git checkout main && git pull origin main && git checkout -b cursor/strict/duckplayer-native
24```
25
26## Files (20 errors total)
27
28### `injected/src/features/duck-player-native.js` (4 errors)
29```
30(28,5): error TS2564: Property 'currentPage' has no initializer.
31(30,5): error TS2564: Property 't' has no initializer.
32(32,16): error TS7006: Parameter 'args' implicitly has an 'any' type.
33(53,27): error TS2322: Type 'string | undefined' is not assignable to type 'string'.
34```
35
36### `injected/src/features/duckplayer-native/custom-error/custom-error.js` (2 errors)
37```
38(26,5): error TS2564: Property 'logger' has no initializer.
39(30,5): error TS2564: Property 'error' has no initializer.
40```
41
42### `injected/src/features/duckplayer-native/messages.js` (3 errors)
43```
44(67,75): error TS2345: Argument of type '(mediaControlSettings: MediaControlSettings) => void' is not assignable to parameter of type '(value: unknown) => void'.
45(75,72): error TS2345: Argument of type '(muteSettings: MuteSettings) => void' is not assignable to parameter of type '(value: unknown) => void'.
46(83,72): error TS2345: Argument of type '(urlSettings: UrlChangeSettings) => void' is not assignable to parameter of type '(value: unknown) => void'.
47```
48
49### `injected/src/features/duckplayer-native/overlays/thumbnail-overlay.js` (3 errors)
50```
51(16,5): error TS2564: Property 'logger' has no initializer.
52(20,5): error TS2564: Property 'container' has no initializer.
53(22,5): error TS2564: Property 'href' has no initializer.
54```
55
56### `injected/src/features/duckplayer-native/sub-features/duck-player-native-no-cookie.js` (1 error)
57```
58(43,30): error TS7006: Parameter 'timestamp' implicitly has an 'any' type.
59```
60
61### `injected/src/features/duckplayer-native/sub-features/duck-player-native-youtube.js` (1 error)
62```
63(56,30): error TS7006: Parameter 'timestamp' implicitly has an 'any' type.
64```
65
66### `injected/src/features/duckplayer-native/youtube-errors.js` (6 errors)
67```
68(50,9): error TS2322: Type 'YouTubeError | undefined' is not assignable to type 'YouTubeError'.
69(62,57): error TS2339: Property 'get' does not exist on type 'object'.
70(80,17): error TS2322: Type 'YouTubeError | undefined' is not assignable to type 'YouTubeError'.
71(85,13): error TS2322: Type 'YouTubeError | undefined' is not assignable to type 'YouTubeError'.
72(93,13): error TS2322: Type 'YouTubeError | undefined' is not assignable to type 'YouTubeError'.
73(101,5): error TS2322: Type 'YouTubeError | undefined' is not assignable to type 'YouTubeError'.
74```
75
76## Fix Patterns
77
78- **TS2564** (No initializer): Use `/** @type {X} */ (prop!)` or initialize. For class properties assigned in `init()` rather than constructor, use definite assignment assertion.
79- **TS7006** (Parameter implicitly any): Add `@param {Type}` JSDoc.
80- **TS2345** (Subscribe callback): The messaging `subscribe` expects `(value: unknown) => void`. Cast or add type guard inside the callback.
81- **TS2322** (YouTubeError | undefined → YouTubeError): Add undefined checks or use non-null assertion where the value is guaranteed.
82- **TS2339** (Property 'get' on object): Cast to `Map` or the actual type that has `.get()`.
83
84## Workflow
85
861. `npm ci`
872. Add all 7 files to CORE_FILES in `scripts/check-strict-core.js`
883. Fix each file's errors
894. `npm run tsc-strict-core` — must pass
905. `npm run test-unit` — must pass
916. `npm run lint` — must pass (run `npm run lint-fix` first if needed)
927. Commit: `fix(types): add strict checking for duckplayer-native files`
938. `git push -u origin cursor/strict/duckplayer-native`
94
95## Constraints
96
97- Do NOT use `any` — use `unknown`, specific types, or proper interfaces
98- Do NOT use `@ts-ignore` or `@ts-expect-error`
99- Do NOT modify files outside the assigned list (except `scripts/check-strict-core.js`)
100- Do NOT remove existing CORE_FILES entries
101- Preserve existing behavior — type fixes only, no logic changes
102
@@ −1 +1 @@
1−# Content Scope Scripts (C-S-S)
1+---
2+description: "Subagent task: Fix strict TypeScript errors in duckplayer-native files and add to CORE_FILES"
3+globs:
4+ - "scripts/check-strict-core.js"
5+ - "injected/src/features/duck-player-native.js"
6+ - "injected/src/features/duckplayer-native/custom-error/custom-error.js"
7+ - "injected/src/features/duckplayer-native/messages.js"
8+ - "injected/src/features/duckplayer-native/overlays/thumbnail-overlay.js"
9+ - "injected/src/features/duckplayer-native/sub-features/duck-player-native-no-cookie.js"
10+ - "injected/src/features/duckplayer-native/sub-features/duck-player-native-youtube.js"
11+ - "injected/src/features/duckplayer-native/youtube-errors.js"
12+---
213
3−Shared JavaScript projects powering privacy features and special pages in DuckDuckGo's native apps (macOS, Windows, iOS, Android).
14+# Strict TypeScript: DuckPlayer Native
415
5−## Workspaces
16+## Task
617
7−This is an npm workspace monorepo with four sub-projects:
18+Fix all strict-mode TypeScript errors in 7 duckplayer-native files and add them to `CORE_FILES`.
819
9−### `injected/` - Browser Privacy Features
20+## Branch
1021
11−JavaScript features injected into web pages for privacy protections. Features extend `ConfigFeature` and integrate with remote configuration for per-site enable/disable.
22+```
23+git checkout main && git pull origin main && git checkout -b cursor/strict/duckplayer-native
24+```
1225
13−**Features** (in `injected/src/features/`):
14−- `api-manipulation` - API behavior modifications
15−- `autofill-import` - Credential import support
16−- `breakage-reporting` - Site breakage reports
17−- `broker-protection` - Data broker removal automation
18−- `click-to-load` - Social embed blocking
19−- `cookie` - Cookie management
20−- `duck-player` / `duck-player-native` - YouTube privacy player
21−- `element-hiding` - Hide page elements
22−- `exception-handler` - Error handling
23−- `favicon` - Favicon privacy
24−- `fingerprinting-*` - Audio, battery, canvas, hardware, screen, storage fingerprint protection
25−- `google-rejected` - Google rejection handling
26−- `gpc` - Global Privacy Control
27−- `harmful-apis` - Dangerous API restrictions
28−- `message-bridge` - Page↔content script messaging
29−- `navigator-interface` - Navigator API modifications
30−- `performance-metrics` - Performance tracking
31−- `referrer` - Referrer protection
32−- `web-compat` - Site compatibility fixes
33−- `web-interference-detection` / `web-telemetry` - Monitoring
26+## Files (20 errors total)
3427
35−**Docs:** `injected/docs/README.md` (index to all docs)
28+### `injected/src/features/duck-player-native.js` (4 errors)
29+```
30+(28,5): error TS2564: Property 'currentPage' has no initializer.
31+(30,5): error TS2564: Property 't' has no initializer.
32+(32,16): error TS7006: Parameter 'args' implicitly has an 'any' type.
33+(53,27): error TS2322: Type 'string | undefined' is not assignable to type 'string'.
34+```
3635
37−### `special-pages/` - Embedded Browser Pages
36+### `injected/src/features/duckplayer-native/custom-error/custom-error.js` (2 errors)
37+```
38+(26,5): error TS2564: Property 'logger' has no initializer.
39+(30,5): error TS2564: Property 'error' has no initializer.
40+```
3841
39−Preact-based HTML/CSS/JS applications embedded in browsers. Each page lives in `special-pages/pages/<name>/`.
42+### `injected/src/features/duckplayer-native/messages.js` (3 errors)
43+```
44+(67,75): error TS2345: Argument of type '(mediaControlSettings: MediaControlSettings) => void' is not assignable to parameter of type '(value: unknown) => void'.
45+(75,72): error TS2345: Argument of type '(muteSettings: MuteSettings) => void' is not assignable to parameter of type '(value: unknown) => void'.
46+(83,72): error TS2345: Argument of type '(urlSettings: UrlChangeSettings) => void' is not assignable to parameter of type '(value: unknown) => void'.
47+```
4048
41−**Pages:**
42−- `duckplayer` - YouTube privacy player UI
43−- `errorpage` - Browser error pages
44−- `example` - Template for new pages
45−- `history` - Browsing history viewer
46−- `new-tab` - New Tab Page
47−- `onboarding` - First-run experience
48−- `release-notes` - Browser release notes
49−- `special-error` - SSL/certificate error pages
49+### `injected/src/features/duckplayer-native/overlays/thumbnail-overlay.js` (3 errors)
50+```
51+(16,5): error TS2564: Property 'logger' has no initializer.
52+(20,5): error TS2564: Property 'container' has no initializer.
53+(22,5): error TS2564: Property 'href' has no initializer.
54+```
5055
51−**Docs:** `special-pages/README.md`, plus `readme.md` in each page directory
56+### `injected/src/features/duckplayer-native/sub-features/duck-player-native-no-cookie.js` (1 error)
57+```
58+(43,30): error TS7006: Parameter 'timestamp' implicitly has an 'any' type.
59+```
5260
53−### `messaging/` - Web-Native Communication
61+### `injected/src/features/duckplayer-native/sub-features/duck-player-native-youtube.js` (1 error)
62+```
63+(56,30): error TS7006: Parameter 'timestamp' implicitly has an 'any' type.
64+```
5465
55−Abstraction layer for web↔native messaging: `notify` (fire-and-forget), `request` (async response), `subscribe` (push updates).
66+### `injected/src/features/duckplayer-native/youtube-errors.js` (6 errors)
67+```
68+(50,9): error TS2322: Type 'YouTubeError | undefined' is not assignable to type 'YouTubeError'.
69+(62,57): error TS2339: Property 'get' does not exist on type 'object'.
70+(80,17): error TS2322: Type 'YouTubeError | undefined' is not assignable to type 'YouTubeError'.
71+(85,13): error TS2322: Type 'YouTubeError | undefined' is not assignable to type 'YouTubeError'.
72+(93,13): error TS2322: Type 'YouTubeError | undefined' is not assignable to type 'YouTubeError'.
73+(101,5): error TS2322: Type 'YouTubeError | undefined' is not assignable to type 'YouTubeError'.
74+```
5675
57−**Docs:** `messaging/docs/messaging.md`
76+## Fix Patterns
5877
59−### `types-generator/` - Schema to TypeScript
78+- **TS2564** (No initializer): Use `/** @type {X} */ (prop!)` or initialize. For class properties assigned in `init()` rather than constructor, use definite assignment assertion.
79+- **TS7006** (Parameter implicitly any): Add `@param {Type}` JSDoc.
80+- **TS2345** (Subscribe callback): The messaging `subscribe` expects `(value: unknown) => void`. Cast or add type guard inside the callback.
81+- **TS2322** (YouTubeError | undefined → YouTubeError): Add undefined checks or use non-null assertion where the value is guaranteed.
82+- **TS2339** (Property 'get' on object): Cast to `Map` or the actual type that has `.get()`.
6083
61−Generates TypeScript types from JSON Schema files. Used by other workspaces.
84+## Workflow
6285
63−## Commands
86+1. `npm ci`
87+2. Add all 7 files to CORE_FILES in `scripts/check-strict-core.js`
88+3. Fix each file's errors
89+4. `npm run tsc-strict-core` — must pass
90+5. `npm run test-unit` — must pass
91+6. `npm run lint` — must pass (run `npm run lint-fix` first if needed)
92+7. Commit: `fix(types): add strict checking for duckplayer-native files`
93+8. `git push -u origin cursor/strict/duckplayer-native`
6494
65−Run from root. Use `nvm use` to set the correct Node version.
95+## Constraints
6696
67−| Command | Purpose |
68−|---------|---------|
69−| `npm run build` | Build all workspaces |
70−| `npm run test-unit` | Unit tests (all workspaces) |
71−| `npm run test-int` | Integration tests (Playwright) |
72−| `npm run lint` | ESLint + TypeScript + Prettier |
73−| `npm run lint-fix` | Auto-fix lint issues |
74−| `npm run serve` | Serve injected test pages (port 3220) |
75−| `npm run serve-special-pages` | Serve special pages (port 3221) |
76−
77−## Coding Standards
78−
79−Follow the error handling guidelines in [`guides/error-handling.md`](guides/error-handling.md). Key rules:
80−- Errors are for **exceptional conditions** (invariant violations, unreachable code), not control flow
81−- Never leave promises unhandled — use `.catch()` or `try/catch` with `await`
82−- Return `null`/sentinel values for expected missing data instead of throwing
83−
84−### Strict TypeScript
85−
86−All **new** source files under `injected/src/` must be added to the `CORE_FILES` set in `scripts/check-strict-core.js`. This enforces TypeScript strict mode (`strict: true`, `noUncheckedIndexedAccess`). Run `npm run tsc-strict-core` to verify. Do not remove existing entries from the set.
87−
88−## Debugging
89−
90−See [`guides/debugging.md`](guides/debugging.md) for debugging resources including script integrity validation, feature triage checklist, and platform-specific troubleshooting.
91−
92−## Notes
93−
94−- When running Playwright commands, use `--reporter list` to prevent the Shell tool from hanging
95−- Use `.github/pull_request_template.md` when creating a pull request.
96−
97−## Local dev quick wins (common pain points)
98−
99−- **Special Pages CSS local dev**: use `npm run serve-special-pages` (repo root) + `npm run watch -- --page=<page>` (inside `special-pages/`) for hot CSS reload (usually `http://localhost:8000/`). The `build/` output does **not** auto-update in watch mode.
100−- **Release workflow**: releases are created from GitHub Actions (see `CONTRIBUTING.md` → “Release Process”). For most iteration, prefer Netlify preview URLs or `npm link` into native apps; only cut a release when you need native consumption via the `releases` branch artifacts.
101−
102−## Cursor Cloud specific instructions
103−
104−- Node 22 and npm are pre-installed. Playwright browsers + system deps are pre-installed. Just run `npm ci` to refresh dependencies.
105−- `npm run serve-special-pages` actually serves on **port 3210** (not 3221 as the Commands table above states). The injected test pages serve on port 3220 as documented.
106−- Integration tests for injected workspace may show 2 flaky iOS mobile drawer timeouts (`duckplayer-mobile-drawer.spec.js`); these are pre-existing timing issues, not environment problems.
107−- No Docker, databases, or external services are needed. All tests are self-contained with local HTTP servers and mocked native messaging.
108−- On headless Linux, `xvfb` is pre-installed. The injected workspace provides `npm run test-int-x` which wraps Playwright with `xvfb-run`, but standard `npm run test-int` also works in this environment.
97+- Do NOT use `any` — use `unknown`, specific types, or proper interfaces
98+- Do NOT use `@ts-ignore` or `@ts-expect-error`
99+- Do NOT modify files outside the assigned list (except `scripts/check-strict-core.js`)
100+- Do NOT remove existing CORE_FILES entries
101+- Preserve existing behavior — type fixes only, no logic changes
109102
