## ℹ️ Description
- Link to the related issue(s): Issue #
- Fixes drift where `pdm run app download` wrote timestamp values in
YAML-native datetime form that could violate `schemas/ad.schema.json`
string expectations.
- Ensures downloaded ads persist `created_on`/`updated_on` as
JSON-serialized ISO-8601 strings and adds a regression test validating
written YAML against the schema.
## 📋 Changes Summary
- Updated downloader save path to use `ad_cfg.model_dump(mode =
\"json\")` before writing YAML in `src/kleinanzeigen_bot/extract.py`.
- Updated existing `download_ad` unit assertion to match JSON-mode
serialization.
- Added `test_download_ad_writes_schema_compliant_yaml` in
`tests/unit/test_extract.py` that writes a real tmp YAML file and
validates it against `schemas/ad.schema.json` with `jsonschema`.
- Added dev dependency `jsonschema>=4.26.0` (and lockfile updates).
- Dependencies/config updates introduced: new dev dependency
(`jsonschema`) for full schema validation in tests.
### ⚙️ Type of Change
- [x] 🐞 Bug fix (non-breaking change which fixes an issue)
- [ ] ✨ New feature (adds new functionality without breaking existing
usage)
- [ ] 💥 Breaking change (changes that might break existing user setups,
scripts, or configurations)
## ✅ Checklist
- [x] I have reviewed my changes to ensure they meet the project's
standards.
- [x] I have tested my changes and ensured that all tests pass (`pdm run
test`).
- [x] I have formatted the code (`pdm run format`).
- [x] I have verified that linting passes (`pdm run lint`).
- [x] I have updated documentation where necessary.
By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
# Release Notes
* **Bug Fixes**
* Improved ad data serialization to ensure consistent JSON format when
saving ad configurations.
* **Tests**
* Added schema validation tests to verify ad YAML output compliance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## ℹ️ Description
*Provide a concise summary of the changes introduced in this pull
request.*
- Link to the related issue(s): n/a
- Describe the motivation and context for this change.
This replaces the stacked XPath work from #845 with a standalone fix
from `main`. It makes `By.XPATH` use the native page XPath API instead
of routing XPath selectors through text lookup.
## 📋 Changes Summary
- Add private XPath helpers in `WebScrapingMixin` for first-match and
all-match lookups.
- Route `By.XPATH` in `_web_find_once()` and `_web_find_all_once()`
through `page.xpath(...)`.
- Add unit coverage for XPath helper behavior, empty results, and
unsupported parent scoping.
- No configuration changes or new dependencies.
### ⚙️ Type of Change
Select the type(s) of change(s) included in this pull request:
- [x] 🐞 Bug fix (non-breaking change which fixes an issue)
- [ ] ✨ New feature (adds new functionality without breaking existing
usage)
- [ ] 💥 Breaking change (changes that might break existing user setups,
scripts, or configurations)
## ✅ Checklist
Before requesting a review, confirm the following:
- [x] I have reviewed my changes to ensure they meet the project's
standards.
- [x] I have tested my changes and ensured that all tests pass (`pdm run
test`).
- [x] I have formatted the code (`pdm run format`).
- [x] I have verified that linting passes (`pdm run lint`).
- [x] I have updated documentation where necessary.
By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactoring**
* Improved web scraping element selection reliability through
streamlined XPath operations and better internal helper methods.
* **Tests**
* Added comprehensive unit tests for XPath-based element lookup
operations to ensure consistent behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
- When an invalid `--ads` value is explicitly provided (e.g.
`--ads=my-directory-name`), the bot now exits with code 2 and a clear
error message listing valid options, instead of silently falling back to
the command default
- Fixes the numeric ID regex from unanchored `\d+[,\d+]*` (which could
match partial strings like `abc123`) to anchored `^\d+(,\d+)*$`
- Adds `_is_valid_ads_selector()` helper to deduplicate validation logic
across publish/update/download/extend commands
## Motivation
When calling `kleinanzeigen-bot publish --ads=led-grow-light-set`
(passing a directory name instead of a numeric ad ID), the bot silently
fell back to `--ads=due` and republished all due ads — causing
unintended republication of multiple ads and loss of conversations on
those ads.
The silent fallback with only a WARNING log message makes it too easy to
accidentally trigger unwanted operations. An explicit error with exit
code 2 (consistent with other argument validation like
`--workspace-mode`) is the expected behavior for invalid arguments.
## Changes
| File | Change |
|------|--------|
| `src/kleinanzeigen_bot/__init__.py` | Added `_ads_selector_explicit`
flag (set when `--ads` or `--force` is used), `_is_valid_ads_selector()`
helper method, and updated all 4 command blocks
(publish/update/download/extend) to error on explicitly invalid
selectors |
| `resources/translations.de.yaml` | Replaced 3 old fallback messages
with 4 new error messages |
| `tests/unit/test_init.py` | Updated 2 existing tests to expect
`SystemExit(2)` instead of silent fallback, added 2 new tests for
update/extend invalid selectors |
## Test plan
- [x] All 754 unit tests pass (`pdm run utest`)
- [x] Lint clean (`pdm run lint`)
- [x] Translation completeness verified
(`test_all_log_messages_have_translations`,
`test_no_obsolete_translations`)
- [x] `--ads=invalid` on publish/update/download/extend all exit with
code 2
- [x] Default behavior (no `--ads` flag) unchanged for all commands
- [x] Valid selectors (`--ads=all`, `--ads=due`, `--ads=12345,67890`,
`--ads=changed,due`) still work
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Stricter validation of ad selectors; invalid selectors now terminate
with exit code 2 and preserve safe defaults when no selector is
provided.
* **New Features**
* Support for comma-separated numeric ID lists as a valid selector
format.
* **Tests**
* Unit tests updated to assert non-zero exit on invalid selectors and
verify default-fallback behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Liermann Torsten - Hays <liermann.hays@partner.akdb.de>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## ℹ️ Description
- Link to the related issue(s): N/A
- Add a CI guard that fails when generated artifacts are out of sync,
motivated by preventing missing schema updates and keeping generated
reference files current.
- Add a committed `docs/config.default.yaml` as a user-facing default
configuration reference.
## 📋 Changes Summary
- Add `scripts/check_generated_artifacts.py` to regenerate schema
artifacts and compare tracked outputs (`schemas/*.json` and
`docs/config.default.yaml`) against generated content.
- Run the new artifact consistency check in CI via
`.github/workflows/build.yml`.
- Add `pdm run generate-config` and `pdm run generate-artifacts` tasks,
with a cross-platform-safe delete in `generate-config`.
- Add generated `docs/config.default.yaml` and document it in
`docs/CONFIGURATION.md`.
- Update `schemas/config.schema.json` with the
`diagnostics.timing_collection` property generated from the model.
### ⚙️ Type of Change
Select the type(s) of change(s) included in this pull request:
- [ ] 🐞 Bug fix (non-breaking change which fixes an issue)
- [x] ✨ New feature (adds new functionality without breaking existing
usage)
- [ ] 💥 Breaking change (changes that might break existing user setups,
scripts, or configurations)
## ✅ Checklist
Before requesting a review, confirm the following:
- [x] I have reviewed my changes to ensure they meet the project's
standards.
- [x] I have tested my changes and ensured that all tests pass (`pdm run
test`).
- [x] I have formatted the code (`pdm run format`).
- [x] I have verified that linting passes (`pdm run lint`).
- [x] I have updated documentation where necessary.
By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Added a reference link to the default configuration snapshot for
easier access to baseline settings.
* **Chores**
* Added a CI build-time check that validates generated schemas and the
default config and alerts when regeneration is needed.
* Added scripts to generate the default config and to sequence artifact
generation.
* Added a utility to produce standardized schema content and compare
generated artifacts.
* Minor tweak to schema generation success messaging.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## ℹ️ Description
This pull request fixes Windows browser auto-detection failures reported
by users where `diagnose`/startup could not find an installed browser
even when Chrome or Edge were present in standard locations. It also
makes diagnostics resilient when auto-detection fails by avoiding an
assertion-driven abort and continuing with a clear failure log.
- Link to the related issue(s): Issue #815
- Describe the motivation and context for this change.
- Users reported `Installed browser could not be detected` on Windows
despite having a browser installed.
- The previous Windows candidate list used a mix of incomplete paths and
direct `os.environ[...]` lookups that could raise when variables were
missing.
- The updated path candidates and ordering were aligned with common
Windows install locations used by Playwright’s channel/executable
resolution logic (Chrome/Edge under `LOCALAPPDATA`, `PROGRAMFILES`, and
`PROGRAMFILES(X86)`).
## 📋 Changes Summary
- Expanded Windows browser path candidates in `get_compatible_browser()`
to include common Google Chrome and Microsoft Edge install paths, while
keeping Chromium and PATH fallbacks.
- Replaced unsafe direct env-var indexing with safe retrieval
(`os.environ.get(...)`) and added a fallback derivation for
`LOCALAPPDATA` via `USERPROFILE\\AppData\\Local` when needed.
- Kept legacy Chrome path candidates
(`...\\Chrome\\Application\\chrome.exe`) as compatibility fallback.
- Updated diagnostics flow to catch browser auto-detection assertion
failures and continue with `(fail) No compatible browser found` instead
of crashing.
- Added/updated unit tests to verify:
- Windows detection for LocalAppData Chrome/Edge/Chromium paths.
- Missing Windows env vars no longer cause key lookup failures and still
surface the intended final detection assertion.
- `diagnose_browser_issues()` handles auto-detection assertion failures
without raising and logs the expected failure message.
### ⚙️ Type of Change
Select the type(s) of change(s) included in this pull request:
- [x] 🐞 Bug fix (non-breaking change which fixes an issue)
## ✅ Checklist
Before requesting a review, confirm the following:
- [x] I have reviewed my changes to ensure they meet the project's
standards.
- [x] I have tested my changes and ensured that all tests pass (`pdm run
test`).
- [x] I have formatted the code (`pdm run format`).
- [x] I have verified that linting passes (`pdm run lint`).
- [x] I have updated documentation where necessary.
By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Hardened Windows browser auto-detection: checks additional common
installation locations for Chrome/Chromium/Edge and treats detection
failures as non-fatal, allowing diagnostics to continue with fallback
behavior and debug logging when no browser is found.
* **Tests**
* Expanded Windows detection tests to cover more path scenarios and
added cases verifying failure-mode diagnostics and logging.
* **Style**
* Minor formatting tweak in default configuration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Bumps the all-actions group with 2 updates:
[vegardit/fast-apt-mirror.sh](https://github.com/vegardit/fast-apt-mirror.sh)
and [github/codeql-action](https://github.com/github/codeql-action).
Updates `vegardit/fast-apt-mirror.sh` from 1.4.1 to 1.4.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vegardit/fast-apt-mirror.sh/releases">vegardit/fast-apt-mirror.sh's
releases</a>.</em></p>
<blockquote>
<h2>1.4.2</h2>
<h2>What's Changed</h2>
<h3>Fixed</h3>
<ul>
<li>prevent Ubuntu ARM switching to non-ubuntu-ports mirrors</li>
<li>prevent invalid fastest mirror selection with ignore-sync-state</li>
<li>avoid pipefail/ERR-trap corrupting fastest mirror detection</li>
<li>Option --exclude-current not working reliably and support ARM</li>
<li>Multiple /etc/*-release files can cause wrong distro detection <a
href="https://redirect.github.com/vegardit/fast-apt-mirror.sh/issues/12">#12</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/vegardit/fast-apt-mirror.sh/compare/1.4.1...1.4.2">https://github.com/vegardit/fast-apt-mirror.sh/compare/1.4.1...1.4.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="29a5ef3401"><code>29a5ef3</code></a>
fix(find): prevent Ubuntu ARM switching to non-ubuntu-ports mirrors</li>
<li><a
href="f3f6ac867d"><code>f3f6ac8</code></a>
fix(find): keep Ubuntu ARM mirror candidates on ubuntu-ports</li>
<li><a
href="77bc0f4f48"><code>77bc0f4</code></a>
fix(find): harden sync baseline and fallback to reachable mirrors</li>
<li><a
href="e4cfe62e1a"><code>e4cfe62</code></a>
fix(find): use InRelease for Ubuntu ARM healthchecks</li>
<li><a
href="85bc4a4115"><code>85bc4a4</code></a>
fix(action): simplify fast-apt-mirror.sh setup</li>
<li><a
href="61f5fd911b"><code>61f5fd9</code></a>
fix(find): avoid pipefail/ERR-trap corrupting fastest mirror
detection</li>
<li><a
href="7ee8df396d"><code>7ee8df3</code></a>
fix: dedup mirror URLs</li>
<li><a
href="3b80eadc89"><code>3b80ead</code></a>
fix: refine mirror health checks and exclude 404 mirrors</li>
<li><a
href="39824222f5"><code>3982422</code></a>
fix: prevent invalid fastest mirror selection with
ignore-sync-state</li>
<li><a
href="4c4ae91025"><code>4c4ae91</code></a>
ci(deps): bump actions/checkout from 4 to 6</li>
<li>Additional commits viewable in <a
href="e5288ed7a1...29a5ef3401">compare
view</a></li>
</ul>
</details>
<br />
Updates `github/codeql-action` from 4.31.11 to 4.32.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.32.2</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.1">2.24.1</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3460">#3460</a></li>
</ul>
<h2>v4.32.1</h2>
<ul>
<li>A warning is now shown in Default Setup workflow logs if a <a
href="https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries">private
package registry is configured</a> using a GitHub Personal Access Token
(PAT), but no username is configured. <a
href="https://redirect.github.com/github/codeql-action/pull/3422">#3422</a></li>
<li>Fixed a bug which caused the CodeQL Action to fail when repository
properties cannot successfully be retrieved. <a
href="https://redirect.github.com/github/codeql-action/pull/3421">#3421</a></li>
</ul>
<h2>v4.32.0</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.0">2.24.0</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3425">#3425</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>4.32.2 - 05 Feb 2026</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.1">2.24.1</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3460">#3460</a></li>
</ul>
<h2>4.32.1 - 02 Feb 2026</h2>
<ul>
<li>A warning is now shown in Default Setup workflow logs if a <a
href="https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries">private
package registry is configured</a> using a GitHub Personal Access Token
(PAT), but no username is configured. <a
href="https://redirect.github.com/github/codeql-action/pull/3422">#3422</a></li>
<li>Fixed a bug which caused the CodeQL Action to fail when repository
properties cannot successfully be retrieved. <a
href="https://redirect.github.com/github/codeql-action/pull/3421">#3421</a></li>
</ul>
<h2>4.32.0 - 26 Jan 2026</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.0">2.24.0</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3425">#3425</a></li>
</ul>
<h2>4.31.11 - 23 Jan 2026</h2>
<ul>
<li>When running a Default Setup workflow with <a
href="https://docs.github.com/en/actions/how-tos/monitor-workflows/enable-debug-logging">Actions
debugging enabled</a>, the CodeQL Action will now use more unique names
when uploading logs from the Dependabot authentication proxy as workflow
artifacts. This ensures that the artifact names do not clash between
multiple jobs in a build matrix. <a
href="https://redirect.github.com/github/codeql-action/pull/3409">#3409</a></li>
<li>Improved error handling throughout the CodeQL Action. <a
href="https://redirect.github.com/github/codeql-action/pull/3415">#3415</a></li>
<li>Added experimental support for automatically excluding <a
href="https://docs.github.com/en/repositories/working-with-files/managing-files/customizing-how-changed-files-appear-on-github">generated
files</a> from the analysis. This feature is not currently enabled for
any analysis. In the future, it may be enabled by default for some
GitHub-managed analyses. <a
href="https://redirect.github.com/github/codeql-action/pull/3318">#3318</a></li>
<li>The changelog extracts that are included with releases of the CodeQL
Action are now shorter to avoid duplicated information from appearing in
Dependabot PRs. <a
href="https://redirect.github.com/github/codeql-action/pull/3403">#3403</a></li>
</ul>
<h2>4.31.10 - 12 Jan 2026</h2>
<ul>
<li>Update default CodeQL bundle version to 2.23.9. <a
href="https://redirect.github.com/github/codeql-action/pull/3393">#3393</a></li>
</ul>
<h2>4.31.9 - 16 Dec 2025</h2>
<p>No user facing changes.</p>
<h2>4.31.8 - 11 Dec 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.23.8. <a
href="https://redirect.github.com/github/codeql-action/pull/3354">#3354</a></li>
</ul>
<h2>4.31.7 - 05 Dec 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.23.7. <a
href="https://redirect.github.com/github/codeql-action/pull/3343">#3343</a></li>
</ul>
<h2>4.31.6 - 01 Dec 2025</h2>
<p>No user facing changes.</p>
<h2>4.31.5 - 24 Nov 2025</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="45cbd0c69e"><code>45cbd0c</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3461">#3461</a>
from github/update-v4.32.2-7aee93297</li>
<li><a
href="cb528be87e"><code>cb528be</code></a>
Update changelog for v4.32.2</li>
<li><a
href="7aee932974"><code>7aee932</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3460">#3460</a>
from github/update-bundle/codeql-bundle-v2.24.1</li>
<li><a
href="b5f028a984"><code>b5f028a</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3457">#3457</a>
from github/dependabot/npm_and_yarn/npm-minor-4c1fc3...</li>
<li><a
href="9702c27ab9"><code>9702c27</code></a>
Merge branch 'main' into
dependabot/npm_and_yarn/npm-minor-4c1fc3d0aa</li>
<li><a
href="c36c94846f"><code>c36c948</code></a>
Add changelog note</li>
<li><a
href="3d0331896c"><code>3d03318</code></a>
Update default bundle to codeql-bundle-v2.24.1</li>
<li><a
href="77591e2c4a"><code>77591e2</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3459">#3459</a>
from github/copilot/fix-github-actions-workflow-again</li>
<li><a
href="7a44a9db3f"><code>7a44a9d</code></a>
Fix Rebuild Action workflow by adding --no-edit flag to git merge
--continue</li>
<li><a
href="e2ac371513"><code>e2ac371</code></a>
Initial plan</li>
<li>Additional commits viewable in <a
href="19b2f06db2...45cbd0c69e">compare
view</a></li>
</ul>
</details>
<br />
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## ℹ️ Description
*Provide a concise summary of the changes introduced in this pull
request.*
- Link to the related issue(s): Closes#789 (completes the fix started
in #793)
- **Motivation**: Fix JSON API pagination for accounts with >25 ads.
Aligns pagination logic with weidi’s approach (starts at page 1), while
hardening error handling and tests. Based on
https://github.com/weidi/kleinanzeigen-bot/pull/1.
## 📋 Changes Summary
- Added pagination helper to fetch all published ads and use it in
delete/extend/publish/update flows
- Added robust handling for malformed JSON payloads and unexpected ads
types (with translated warnings)
- Improved sell_directly extraction with pagination, bounds checks, and
shared coercion helper
- Added/updated tests for pagination and edge cases; updated assertions
to pytest.fail style
### ⚙️ Type of Change
Select the type(s) of change(s) included in this pull request:
- [x] 🐞 Bug fix (non-breaking change which fixes an issue)
- [ ] ✨ New feature (adds new functionality without breaking existing
usage)
- [ ] 💥 Breaking change (changes that might break existing user setups,
scripts, or configurations)
## ✅ Checklist
Before requesting a review, confirm the following:
- [x] I have reviewed my changes to ensure they meet the project's
standards.
- [x] I have tested my changes and ensured that all tests pass (`pdm run
test:cov:unified`).
- [x] I have formatted the code (`pdm run format`).
- [x] I have verified that linting passes (`pdm run lint`).
- [x] I have updated documentation where necessary.
By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Reliable multi-page fetching for published ads and buy-now eligibility
checks.
* **Bug Fixes**
* Safer pagination with per-page JSON handling, limits and improved
termination diagnostics; ensures pageNum is used when needed.
* **Tests**
* New comprehensive pagination tests and updates to existing tests to
reflect multi-page behavior.
* **Chores**
* Added a utility to safely coerce page numbers; minor utility signature
cleanup.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## ℹ️ Description
Refactors and reorganizes documentation to improve navigation and keep
the README concise.
- Link to the related issue(s): Issue #N/A
- Describe the motivation and context for this change.
- The README had grown long and duplicated detailed config/ad
references; this consolidates docs into focused guides and adds an
index.
## 📋 Changes Summary
- Add dedicated docs pages for configuration, ad configuration, update
checks, and a docs index.
- Slim README and CONTRIBUTING to reference dedicated guides and clean
up formatting/markdownlint issues.
- Refresh browser troubleshooting and update-check guidance; keep the
update channel name aligned with schema/implementation.
- Add markdownlint configuration for consistent docs formatting.
### ⚙️ Type of Change
Select the type(s) of change(s) included in this pull request:
- [ ] 🐞 Bug fix (non-breaking change which fixes an issue)
- [x] ✨ New feature (adds new functionality without breaking existing
usage)
- [ ] 💥 Breaking change (changes that might break existing user setups,
scripts, or configurations)
## ✅ Checklist
Before requesting a review, confirm the following:
- [x] I have reviewed my changes to ensure they meet the project's
standards.
- [x] I have tested my changes and ensured that all tests pass (`pdm run
test`).
- [x] I have formatted the code (`pdm run format`).
- [x] I have verified that linting passes (`pdm run lint`).
- [x] I have updated documentation where necessary.
By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Reorganized and enhanced contributing guidelines with improved
structure and formatting
* Streamlined README with better organization and updated installation
instructions
* Added comprehensive configuration reference documentation for
configuration and ad settings
* Improved browser troubleshooting guide with updated guidance,
examples, and diagnostic information
* Created new documentation index for easier navigation
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->