Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,12 @@ jobs:
# Codegen freshness is its own step because preflight regenerates the
# files internally — the diff has to be captured against pristine git
# state before preflight runs.
- name: Codegen freshness (site data + injection patterns + rule defaults)
- name: Codegen freshness (site data + injection patterns)
run: |
bun run build-site-data
bun run build-injection-patterns
bun run build-rule-defaults
if ! git diff --exit-code -- src/rules/site-data.generated.ts src/rules/injection-patterns.generated.ts src/rules/rule-defaults.generated.ts; then
echo "::error::Generated files are out of date. Run \`bun run build-site-data && bun run build-injection-patterns && bun run build-rule-defaults\` locally and commit the result."
if ! git diff --exit-code -- src/rules/site-data.generated.ts src/rules/injection-patterns.generated.ts; then
echo "::error::Generated files are out of date. Run \`bun run build-site-data && bun run build-injection-patterns\` locally and commit the result."
exit 1
fi
- name: Preflight (lint + typecheck + knip + test with coverage)
Expand Down
14 changes: 8 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,14 @@ itself, so name collisions and convention drift surface at lint time.
## Rule defaults

The initial enabled/disabled state for each rule lives in
`extension/data/rule-defaults.json`, not on the rule modules themselves. The
codegen in `extension/scripts/build-rule-defaults.ts` validates that every
registered rule id has a default (and that no unknown ids appear) and emits
`extension/src/rules/rule-defaults.generated.ts`, which
`extension/src/lib/storage.ts` imports. Adding a rule without picking a default
fails the build; do not edit the generated file.
`extension/src/rules/rule-metadata.ts`, not on the rule modules themselves. This
hand-edited file is the source of truth for `RuleId`, `RULE_IDS`, and
`RULE_DEFAULTS`; `extension/src/lib/storage.ts` imports it. It is kept out of
`rules/index.ts` so the service-worker bundle doesn't pull rule files' top-level
DOM access. Adding a rule means appending an entry both here and in
`rules/index.ts`; the catalog test in
`extension/src/rules/__tests__/catalog.test.ts` enforces that the two stay in
sync.

`extension/build.ts` accepts a `--defaults <path>` CLI flag (or
`EXTENSION_DEFAULTS_FILE` env var) pointing at a JSON file in the same shape as
Expand Down
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,14 @@ bun run build
### Customize build-time defaults

Which rules ship on by default is enumerated in
[`extension/data/rule-defaults.json`](./extension/data/rule-defaults.json). To
ship a build with a custom set without forking the repo, pass an override file
to `bun run build`. The file is a flat JSON object whose keys are rule ids (same
keys the Options-page export uses) plus a small set of reserved non-rule keys —
currently `optionsButton` (boolean, default off) to enable the floating on-page
button that opens the options page:
[`extension/src/rules/rule-metadata.ts`](./extension/src/rules/rule-metadata.ts).
To ship a build with a custom set without forking the repo, pass an override
file to `bun run build`. The file is a flat JSON object whose keys are rule ids
(same keys the Options-page export uses) plus a small set of reserved non-rule
keys — currently `optionsButton` (boolean, default off) to enable the floating
on-page button that opens the options page. See
[`extension/data/defaults-overrides.example.json`](./extension/data/defaults-overrides.example.json)
for a starting template:

```sh
bun run build --defaults ./my-defaults.json
Expand Down
6 changes: 4 additions & 2 deletions docs/src/content/docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,14 @@ The extension is now active. Reload any open tabs to pick up the content script.
## Customizing defaults at build time

Which rules ship on by default is enumerated in
[`extension/data/rule-defaults.json`](https://github.com/pixiebrix/agent-browser-shield/blob/main/extension/data/rule-defaults.json).
[`extension/src/rules/rule-metadata.ts`](https://github.com/pixiebrix/agent-browser-shield/blob/main/extension/src/rules/rule-metadata.ts).
For one-off changes, edit that file and rebuild.

For infrastructure deployments where the same custom set of defaults should ship
in every build (so an agent doesn't have to flip toggles in the Options page on
each fresh session), pass a JSON override file to `bun run build`:
each fresh session), pass a JSON override file to `bun run build`. A starting
template lives at
[`extension/data/defaults-overrides.example.json`](https://github.com/pixiebrix/agent-browser-shield/blob/main/extension/data/defaults-overrides.example.json):

```sh
cat > my-defaults.json <<'EOF'
Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ grouping the options page uses; rule IDs here match the filenames in
[`extension/src/rules/`](https://github.com/pixiebrix/agent-browser-shield/tree/main/extension/src/rules),
which is the authoritative source for behavior. Initial enabled/disabled state
for each rule lives in
[`extension/data/rule-defaults.json`](https://github.com/pixiebrix/agent-browser-shield/blob/main/extension/data/rule-defaults.json).
[`extension/src/rules/rule-metadata.ts`](https://github.com/pixiebrix/agent-browser-shield/blob/main/extension/src/rules/rule-metadata.ts).
If this page disagrees with either, trust the source. The
[Install page](/install/#customizing-defaults-at-build-time) covers how to
override defaults at build time without forking the repo.
Expand Down
14 changes: 5 additions & 9 deletions extension/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { readFileSync } from "node:fs";
import { cp, mkdir, rm } from "node:fs/promises";
import { isAbsolute, join, resolve } from "node:path";
import { generateInjectionPatterns } from "./scripts/build-injection-patterns";
import { generateRuleDefaults } from "./scripts/build-rule-defaults";
import { generateSiteData } from "./scripts/build-site-data";
import { checkBackgroundPurity } from "./scripts/check-background-purity";
import { loadDefaultOverrides } from "./scripts/load-default-overrides";
Expand Down Expand Up @@ -83,19 +82,16 @@ const defaultsEnvPath = readEnvValue("EXTENSION_DEFAULTS_FILE");
const defaultsPath = defaultsFlagPath ?? (defaultsEnvPath || undefined);

async function build(): Promise<void> {
// Regenerate src/rules/site-data.generated.ts from data/sites/*.yaml,
// src/rules/injection-patterns.generated.ts from data/injection-patterns.yaml,
// and src/rules/rule-defaults.generated.ts from data/rule-defaults.json.
// Regenerate src/rules/site-data.generated.ts from data/sites/*.yaml and
// src/rules/injection-patterns.generated.ts from data/injection-patterns.yaml.
// Cheap and idempotent; ensures dev never forgets to rerun codegen.
generateSiteData();
generateInjectionPatterns();
generateRuleDefaults();

// Resolve the optional --defaults / EXTENSION_DEFAULTS_FILE override
// against the codegen output's RULE_DEFAULTS so the validator knows the
// current rule registry. Importing the generated file after codegen above
// means the rule id set is always fresh.
const { RULE_DEFAULTS } = await import("./src/rules/rule-defaults.generated");
// against the hand-edited RULE_DEFAULTS so the validator knows the current
// rule registry.
const { RULE_DEFAULTS } = await import("./src/rules/rule-metadata");
const knownRuleIds = Object.keys(RULE_DEFAULTS);
const overrides = defaultsPath
? loadDefaultOverrides({
Expand Down
8 changes: 8 additions & 0 deletions extension/data/defaults-overrides.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"reviews-redact": false,
"ads-hide": false,
"irrelevant-sections-redact": true,

"optionsButton": true,
"runOnInactiveTabs": false
}
43 changes: 0 additions & 43 deletions extension/data/rule-defaults.json

This file was deleted.

24 changes: 0 additions & 24 deletions extension/data/rule-defaults.schema.ts

This file was deleted.

14 changes: 7 additions & 7 deletions extension/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,11 +286,11 @@ export default tseslint.config(
},
{
// lib/ owns the runtime engine and shared helpers. It depends on the
// rule catalog (rules/index), the contract (rules/types), and the
// generated defaults table — never on a specific rule implementation.
// Reaching into one rule from lib quietly couples a helper to that
// rule's internals and makes the next rule that needs the same hook
// copy-paste instead of factor.
// rule catalog (rules/index), the contract (rules/types), the
// generated tables, and the hand-edited rule-metadata table — never on
// a specific rule implementation. Reaching into one rule from lib
// quietly couples a helper to that rule's internals and makes the next
// rule that needs the same hook copy-paste instead of factor.
files: ["src/lib/**/*.ts", "src/lib/**/*.tsx"],
ignores: ["src/lib/**/__tests__/**"],
rules: {
Expand All @@ -302,11 +302,11 @@ export default tseslint.config(
target: "./src/lib",
from: "./src/rules/*.ts",
except: [
rulePath("{index,types}.ts"),
rulePath("{index,types,rule-metadata}.ts"),
rulePath("*.generated.ts"),
],
message:
"lib/ may only depend on rules/{index,types,*.generated} — not on a specific rule file.",
"lib/ may only depend on rules/{index,types,rule-metadata,*.generated} — not on a specific rule file.",
},
],
},
Expand Down
3 changes: 1 addition & 2 deletions extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
"fetch-justdeleteme": "uv run --directory .. scripts/fetch_justdeleteme.py",
"build-site-data": "bun run scripts/build-site-data.ts",
"build-injection-patterns": "bun run scripts/build-injection-patterns.ts",
"build-rule-defaults": "bun run scripts/build-rule-defaults.ts",
"build-icons": "bun run scripts/build-icons.ts",
"clean": "rm -rf dist",
"test": "jest",
Expand All @@ -40,7 +39,7 @@
"lint:eslint:fix": "eslint . --fix",
"knip": "knip",
"typecheck": "tsc --noEmit && tsc -p tsconfig.test.json --noEmit",
"preflight": "bun run build-site-data && bun run build-injection-patterns && bun run build-rule-defaults && bun run check && bun run typecheck && bun run knip && bun run test:coverage"
"preflight": "bun run build-site-data && bun run build-injection-patterns && bun run check && bun run typecheck && bun run knip && bun run test:coverage"
},
"dependencies": {
"abort-utils": "^3.0.0",
Expand Down
83 changes: 0 additions & 83 deletions extension/scripts/build-rule-defaults.ts

This file was deleted.

2 changes: 1 addition & 1 deletion extension/scripts/check-background-purity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export function checkBackgroundPurity(): void {
`${relative(ROOT, BUNDLE)} leaks ${leaks.length} rule implementation file(s):\n${sample}${tail}\n\n` +
"The background service worker must not import rule files. Check that " +
"any new lib/* code in the background's import graph uses " +
"`rules/rule-defaults.generated` for RuleId/RULE_IDS rather than " +
"`rules/rule-metadata` for RuleId/RULE_IDS rather than " +
"`rules/index.ts`.",
);
}
Expand Down
Loading
Loading