# Integrations

`duckduckgo-search-cli` integrates with 16+ AI agents and automation platforms
via its stable JSON contract, deterministic exit codes, and zero-dependency
binary install. This file is a pointer to the full integration catalog.

## Full Catalog

See [`docs/INTEGRATIONS.md`](docs/INTEGRATIONS.md) for the complete
integration guide, including:

- 16 supported AI agents (Claude, GPT, Gemini, Cursor, OpenCode, etc.)
- Flag aliases introduced in each version
- Summary table consolidating all integrations
- Per-platform installation recipes
- Exit code semantics for agent decision-making
- Per-integration snippets with `timeout`, `jaq`, and `PIPESTATUS`

## Quick Reference

```bash
# Canonical invocation
timeout 60 duckduckgo-search-cli -q -f json --num 15 "query"

# Exit codes
0  success         → parse .resultados
1  runtime error   → read stderr; retry once with -v
2  config error    → re-run init-config --force
3  anti-bot block  → back off 300+ s; switch --endpoint lite
4  global timeout  → raise --global-timeout; reduce --parallel
5  zero results    → refine query or try different --lang
6  suspected block → inspect .metadados.causa_zero; wait 300s or rotate proxy

# Current version: v0.9.0
```

## v0.9.0 Highlights for Integrations

- **GAP-WS-106 (global flags)** — nine flags are now `global = true` and accepted BEFORE OR AFTER the `deep-research` subcommand: `-q`, `-o`, `-n`, `-f`, `-t`, `-l`, `-c`, `-p`, `-v` (plus their long forms). Pipeline authors no longer need to remember flag ordering relative to the subcommand. Extends the GAP-WS-59 hoisting precedent.
- **GAP-WS-106 (auto-degradation without Chrome)** — `deep-research` in a build without the `chrome` feature (or with `DUCKDUCKGO_SEARCH_CLI_NO_CHROME=1`) NO LONGER aborts with exit 2: it auto-applies `--no-news` with a stderr warning and proceeds web-only. Likewise, `--vertical news|all` downgrades to `Web` with a warning instead of aborting. CI aliases are now portable across chrome/no-chrome builds.
- **GAP-WS-106 (actionable errors)** — when the parser rejects a known flag positioned after the subcommand, a hint is appended pointing to the correct position (rare now that the 9 most-used flags are global).
- **No JSON schema changes** — the envelope is byte-identical to v0.8.9; only parser/exit-code behavior changed.

## v0.8.9 Highlights for Integrations

- **GAP-WS-104 (news vertical, `--vertical` flag)** — new flag `--vertical <web|news|all>` (default `web`). `news` and `all` are Chrome-only (no HTTP fallback), accept any number of queries (multi-query via `--queries-file` or multiple positionals is accepted since GAP-WS-105). `--vertical` is a root-level flag and is NOT accepted inside the `deep-research` subcommand (which has its own news scan).
- **News envelope** — `.noticias[].{posicao,titulo,url}` are guaranteed non-null; `.noticias[].{fonte,data_relativa,thumbnail}` are optional (`Option<String>` — always apply `// ""` fallback in `jaq`). `.quantidade_noticias` and `.metadados.vertical_usada` are present ONLY when vertical != web — web mode output is byte-identical to v0.8.8.
- **New ZeroCause variant `vertical-sem-resultados`** — a news/all search with zero hits is classified as legitimate and emits exit 5 (not exit 6).
- **Exit-code accounting** — the total result count used for exit code decisions is `resultados + quantidade_noticias`.
- **`--fetch-content` scope** — content extraction acts ONLY on `resultados[]` (web); `noticias[]` entries are never fetched.
- **Canonical formula** — `timeout 90 duckduckgo-search-cli --vertical news "query" -q -f json | jaq '.noticias'`
- **News RAG pipeline** — extract guaranteed fields with optional fallbacks:

  ```bash
  timeout 90 duckduckgo-search-cli --vertical news "rust 1.88 release" -q -f json \
    | jaq -r '.noticias[] | [.posicao, .titulo, .url, (.fonte // ""), (.data_relativa // "")] | @tsv'
  ```

- **Combined web + news (`--vertical all`)** — one Chrome pass returns both roots:

  ```bash
  timeout 90 duckduckgo-search-cli --vertical all "query" -q -f json \
    | jaq '{web: [.resultados[].url], news: [.noticias[].url]}'
  ```

- **No breaking changes to JSON output schema**. All v0.8.8 fields remain present. News fields are additive and only emitted when the news vertical is active.

## v0.8.8 Highlights for Integrations

- **GAP-WS-089 fix (Xvfb stale lock cleanup)** — `spawn_virtual_display()` now checks whether the PID inside `/tmp/.X{N}-lock` is alive before skipping the slot. Stale locks from crashed or cancelled runs are removed automatically, preventing Xvfb pool exhaustion after ~100 failed runs.
- **GAP-WS-090 fix (`--num` honored in Chrome headed path)** — Chrome primary search now truncates results to `min(num, len)` before computing `quantidade_resultados`. Previously `--num 1` returned 10 results (a full DDG page).
- **GAP-WS-091 fix (`--region` alias added)** — `--country`/`-c` now accepts `alias = "region"`, aligning the CLI with the SKILL documentation that references `--region`.
- **GAP-WS-092/093/097 fix (`fill_compat_fields()` populates metadados)** — `metadados.quantidade_resultados`, `metadados.endpoint_usado`, and `metadados.nivel_cascata` are now populated via `fill_compat_fields()` before JSON emission. Previously these fields existed only at the root level or were always `null`.
- **GAP-WS-094 fix (`--num` honored in batch/parallel path)** — `execute_query_with_cancellation()` now truncates results by `--num` in the batch path, matching the single-query fix from GAP-WS-090.
- **GAP-WS-095 fix (`identidade_usada` populated in Chrome headed)** — when Chrome headed succeeds with `identity_profile = Auto`, the CLI now looks up the matching identity from the pool by UA and populates `identidade_usada` instead of returning `null`.
- **GAP-WS-099 fix (`ZeroResultsSuspeito` emits exit 6)** — the `ZeroResultsSuspeito` variant was missing from the exit code 6 match arm. It now correctly emits exit 6 (`SUSPECTED_BLOCK`) instead of falling through to exit 5. BC opt-out: `DUCKDUCKGO_ZERO_CAUSE_STRICT=false`.
- **GAP-WS-100 fix (`tamanho_conteudo` reflects truncated size)** — `content_size` now uses `text.len()` (post-truncation) instead of `size_original` (raw HTML body). `--max-content-length 500` now reports `tamanho_conteudo: 500` instead of the original HTML size.
- **GAP-WS-102 fix (deep-research `nivel_cascata` no longer null)** — deep-research metadata now reads from `cascade_level_observed` (the real field) instead of `cascade_level` (the compat field populated after pipeline return).
- **GAP-WS-103 fix (exit 6 documented in `--help`)** — the EXIT CODES section of `--help` now lists exit code 6 (`Suspected block`). Previously only codes 0–5 were documented.
- **No breaking changes to JSON output schema**. All v0.8.7 fields remain present. New compat fields are additive.

## v0.7.10 Highlights for Integrations

- **GAP-WS-60 fix (CRITICAL, identity pin propagation)** — `--identity-profile` agora propaga a identidade selecionada para `failure_output` (pipeline.rs) e `error_output` (parallel.rs) via novo helper `identity_tag_for_cli_identity` em `src/identity.rs`. Antes da fix, o pino de identidade (`identidade_usada`) só aparecia no caminho de SUCESSO; em falha, era sempre `null`. Consumers agora podem correlacionar uma falha a uma identidade específica do pool de 12.
- **GAP-AUD-002 fix (CRITICAL, bench wiring)** — `cargo bench --bench pre_flight_latency` agora roda Criterion corretamente após adicionar `[[bench]] harness = false` em `Cargo.toml`. Antes da fix, o binário do bench era compilado mas invocado pelo test harness, que reportava `running 0 tests` em vez de rodar os 5 cenários. Bench salva resultados em `target/criterion/`.
- **`--require-results` (NEW flag, `deep-research`)** — quando setado e o fan-out agrega zero resultados, o subcomando retorna exit 4 (`GLOBAL_TIMEOUT`) com mensagem `deep-research produced zero results for query ...; --require-results set → exiting non-zero` no stderr. Fecha o GAP-WS-1114 (silent-discard pattern).
- **`--pre-flight` (NEW flag, global)** — ativa o scheduler automático de probe-deep dentro de `execute_single_search`. Quando o ambiente está bloqueado, detecta captcha/ghost-block em ~140ms antes de gastar a query real, e aborta com `pre_flight_blocked` (exit 3). Default `false` para preservar comportamento v0.7.8.
- **`--probe-deep` agora retorna exit 3 quando detecta captcha** (B4 fix, v0.7.10) — antes retornava exit 0 mesmo com `status: "captcha"`. Consumers podem ramificar no exit code em vez de parsear o JSON.
- **Pino de identidade canônico** — formato `<family>-<platform>-<16hex>`, ex.: `chrome-linux-33333333cccc0003`, `firefox-linux-99999999cccc0009`, `safari-macos-bbbbbbbbeeee000b`. Seed determinístico por identidade.
- **Zero breaking changes**. Todos os campos JSON de v0.7.9 permanecem. Schema `SearchMetadata.identity_used: Option<String>` continua opcional (`None` quando `auto` cascade).
- **`scripts/pre-publish-gate.sh` (NEW)** — 7 gates sequenciais antes de `cargo publish`: fmt, clippy, test, coverage ≥80%, sem refs a v0.7.9 stale em `skill/`, publish dry-run válido, CI main verde. Regra 1264 (cargo publish dry-run obrigatório antes do real).

## v0.7.9 Highlights for Integrations

- **GAP-WS-58 fix (CRITICAL, ghost-block)** — `detectar_interstitial` agora classifica body sub-4KB sem `result-page-signal` como `InterstitialKind::Cloudflare`. Helper `has_result_page_signal` checa classes DDG (`nrn-react-div`, `react-article`, `module--results`, `js-react-aria-results`). Threshold conservador de 4KB evita falsos positivos.
- **GAP-WS-59 fix (HIGH, markers 2026)** — 5 marcadores Cloudflare novos (`anomaly.js`, `botnet`, `cf-error-code`, `cf-ray`, `Performance & Security by Cloudflare`) + 1 marker DDG novo (`Unfortunately, bots` parcial). `CLOUDFLARE_MARKERS` e `DDG_MARKERS` atualizados em `src/probe_deep.rs`.
- **GAP-WS-59 fix (HIGH, global flag)** — `--allow-lite-fallback` e `--pre-flight` hoisted para `RootArgs` com `global = true`. Fechou o caminho `unexpected argument` em subcomandos como `deep-research`.
- **Config.pre_flight adicionado** com default `false` para opt-in.
- **Zero breaking changes**. Campos JSON existentes preservados.

## v0.7.8 Highlights for Integrations
## v0.7.5 Highlights for Integrations

- **GAP-WS-29 fixed (CRITICAL, build experience, Windows)** — `cargo install` on native Windows MSVC without the **C++ CMake tools for Windows** sub-component of the Visual Studio Installer previously failed minutes into the BoringSSL build with the cryptic `program not found / is 'cmake' not installed?`. The `build.rs` preflight now detects this and aborts in SECONDS with the exact fix (`winget install -e --id Kitware.Cmake` OR Visual Studio Installer → Modify → Workloads → Desktop development with C++ → expand → check C++ CMake tools for Windows). New escape hatch: `DDG_SKIP_CMAKE_CHECK=1`.
- **GAP-WS-30 fixed (CRITICAL, build experience, Windows)** — BoringSSL CMake uses the Visual Studio 17 2022 generator which requires `cl.exe` (compiler) and `link.exe` (linker). The `build.rs` preflight now detects both and aborts with the fix (open a Developer PowerShell for VS 2022, or run `Launch-VsDevShell.ps1`). MSVC is NOT auto-installed (5+ GB download, too intrusive). New escape hatch: `DDG_SKIP_MSVC_CHECK=1`.
- **GAP-WS-31 fixed (CRITICAL, build experience, Windows)** — BoringSSL perlasm generator emits crypto assembly in NASM format and requires `perl.exe`. The `build.rs` preflight now detects perl and reports the fix (`winget install -e --id StrawberryPerl.StrawberryPerl`). New escape hatch: `DDG_SKIP_PERL_CHECK=1`.
- **GAP-WS-32/35/36 fixed (MEDIUM, documentation)** — All remaining claims that "pre-built binaries from `cargo install` are unaffected" (or its PT/EN variants) are now qualified across `skill/duckduckgo-search-cli-en/SKILL.md`, `skill/duckduckgo-search-cli-pt/SKILL.md`, `llms-full.txt`, `docs/CROSS_PLATFORM.md`, `README.md`, and `README.pt-BR.md`. **`crates.io` NEVER distributes binaries**; `cargo install` always compiles from source. Users on Windows must satisfy the four BoringSSL build prerequisites (NASM, CMake, MSVC, Perl) themselves before `cargo install` can succeed.
- **`build.rs` preflight coverage expanded** — v0.7.4 only checked for NASM. v0.7.5 checks for all four BoringSSL build prerequisites (nasm, cmake, cl.exe, link.exe, perl) and supports four independent `DDG_SKIP_*_CHECK=1` escape hatches.
- **New `scripts/check-windows-toolchain.ps1`** — standalone diagnostic (no installs) that checks all 7 tools (cargo, rustc, cmake, nasm, cl.exe, link.exe, perl) and emits text or JSON output. Exit code 0 if all present, 1 otherwise. Useful for support tickets and CI gates.
- **New `docs/INSTALL-WINDOWS.md` (EN) + `docs/INSTALL-WINDOWS.pt-BR.md` (PT)** — step-by-step guide covering 5 installation methods (VS Installer + standalone; all-winget standalone; Chocolatey; helper script; standalone diagnostic). Includes troubleshooting for each of the 4 GAPs and the `DDG_SKIP_*_CHECK` escape hatches.
- **CI Windows jobs updated** — `.github/workflows/ci.yml` and `.github/workflows/release.yml` now verify CMake, install Perl, and verify MSVC Build Tools (in addition to the existing NASM step) in every Windows job. This eliminates the implicit dependency on the `windows-2022` image's pre-installed tooling.
- **Zero breaking changes to JSON output schema**. All v0.7.4 fields remain present. All v0.7.3 fields remain present.


- **GAP-WS-27 fixed (CRITICAL)**: The macOS CAPTCHA interstitial that returned HTTP 200 with `quantidade_resultados: 0` while Windows returned full results is closed. TLS stack changed from `rustls` to BoringSSL via `wreq 6.0.0-rc.29`. `cargo install` always compiles from source — crates.io does not distribute pre-built binaries for any platform. The build toolchain change is the trade-off for the BoringSSL TLS fix (GAP-WS-27 closed). Source builds on Linux require `cmake`, `perl`, `pkg-config`, and `libclang-dev`; source builds on Windows require NASM, CMake, MSVC, and Perl (see `gaps.md` GAP-WS-28/29/30/31 and `docs/INSTALL-WINDOWS.md`).
- **`session` feature (cookie persistence + warm-up)**:
  - New flags: `--no-warmup`, `--no-cookie-persistence`, `--cookies-path <PATH>`.
  - Cookie jar persisted to `~/.config/duckduckgo-search-cli/cookies.json` (Linux), `%APPDATA%\duckduckgo-search-cli\cookies.json` (Windows), or `~/Library/Application Support/duckduckgo-search-cli/cookies.json` (macOS) with Unix permissions `0o600`.
  - Warm-up adds one `GET https://duckduckgo.com/` before the first real query to populate session cookies.
- **`probe-deep` feature (CAPTCHA interstitial detection)**:
  - New flags: `--probe-deep` (run a real search query and classify the body as `ok` or `captcha`), `--allow-lite-fallback` (opt-in: only takes effect when the `detectar_interstitial` predicate reports `captcha`; in v0.7.8+ the fallback condition is honored end-to-end via GAP-WS-52).
  - New JSON report fields on the probe response: `status`, `cascata_motivo`, `sugestao_mitigacao`, `http_status`, `latency_ms`.
- **Zero breaking changes to JSON output schema**. All v0.7.2 fields remain present.

## v0.7.0 Highlights for Integrations

- **New subcommand `deep-research`**: agents that need multi-hop answers can
  drop in `duckduckgo-search-cli deep-research "question" --synthesize`
  and get a Markdown report back, with no extra orchestration. Inherits
  every global flag (`-q -f json`, `--num`, `--parallel`, `--proxy`,
  `--fetch-content`) plus deep-research-specific knobs
  (`--max-sub-queries`, `--sub-queries-file`, `--aggregate`,
  `--budget-tokens`, `--synth-format`).
- **Backward-compatible**: zero changes to `buscar`, `init-config`,
  default-config JSON schema, or any exit code. Existing pipelines keep
  working unchanged.

## v0.6.5 Highlights for Integrations

- **MP-26 FIX**: Windows build now compiles. Use `cargo install duckduckgo-search-cli`
  on any platform without manual patches.
- **CI-01 FIX**: CI matrix now green on all 3 SOs (Linux/macOS/Windows).
  Agents running on Windows runners can rely on the binary.
- **WS-12 Circuit breaker**: `--fetch-content --parallel` no longer cascades
  failures across hosts — one slow domain won't block the rest of the crawl.
- **WS-25 ProgressBar**: `indicatif` output to stderr auto-hides in pipes,
  so JSON pipelines on stdout stay clean.

See `CHANGELOG.md` for the complete v0.6.5 changelog and migration notes
from earlier versions.


## v0.7.6 Highlights for Integrations

- **GAP-WS-48 closed (HIGH, build experience)**: `cargo install` was breaking
  on certain platforms due to a `cargo` resolver conflict between
  `alloc-no-stdlib 2.0.4` and `alloc-no-stdlib 3.0.0` brought in transitively
  by the `wreq` stack. v0.7.6 pins `alloc-no-stdlib =2.0.4` directly in
  `Cargo.toml`. Reinstalling from crates.io now works without manual
  dependency cleanup.
- **No CLI contract changes**: All v0.7.5 flags, JSON fields, and exit codes
  remain present. Drop-in replacement.
- **CI change**: The `pre-publish` job now resolves the dependency graph
  during release — if the pin ever drifts again, the release will fail
  before reaching crates.io.


## v0.7.7 Highlights for Integrations

- **GAP-WS-49 closed (CRITICAL, runtime regression)**: A `wreq-util`
  resolution failure in v0.7.6 broke BoringSSL TLS fingerprint emulation
  on certain Linux distributions. The result was silent CAPTCHA
  interception on hosts that previously worked. v0.7.7 pins `wreq-util`
  directly in `Cargo.toml` — no more resolution drift.
- **No CLI contract changes**: All v0.7.6 flags, JSON fields, and exit
  codes remain present. Drop-in replacement.
- **Recommended upgrade path**: v0.7.5 → v0.7.7 is the cleanest jump
  for users who skipped v0.7.6. The v0.7.6 → v0.7.7 delta is
  dependency-only.


## v0.7.8 Highlights for Integrations

- **GAP-WS-50**: `probe-deep` interstitial list expanded — 8 Cloudflare
  markers plus 1 DDG anomaly marker. False-negative rate on CAPTCHA
  detection dropped measurably in benchmark runs.
- **GAP-WS-52**: `--allow-lite-fallback` now reads the real detector
  result. When the detector flags a CAPTCHA but the flag is off, the CLI
  emits a structured `tracing::warn!` and exits with the appropriate
  code instead of silently degrading. Surfaces the trade-off to
  integrators.
- **GAP-WS-53**: `-vv` (debug) and `-vvv` (trace) levels added. Operators
  investigating failed searches can escalate verbosity without
  recompiling. The flag `conflicts_with = "quiet"`.
- **GAP-WS-54**: `scraper` bumped to `0.27.0`. Removes the transitive
  `fxhash 0.2.1` (RUSTSEC-2025-0057, unmaintained). `cargo audit
  --deny warnings` is now a blocking gate in CI and release.
- **GAP-WS-55**: `wreq` block in `Cargo.toml` rewritten to match the
  actual pin in use (`6.0.0-rc.29` plus three direct pins). Eliminates
  documentation-vs-code drift.
- **GAP-WS-56**: Legacy `Buscar` subcommand hidden from `--help` via
  `#[command(hide = true)]`. Remains callable for backward compatibility.
- **GAP-WS-57**: `--retries` flag now honored end-to-end in
  `src/parallel.rs:644`. The previous behavior silently dropped the
  value in the `error_output` path. Integrators relying on retry
  behavior will see it actually take effect.
- **No breaking changes to JSON output schema**. All v0.7.7 fields
  remain present. Drop-in replacement once v0.7.8 is published.

See `CHANGELOG.md` for the complete v0.7.6/v0.7.7/v0.7.8 changelog and
the ADR at `docs/decisions/0002-anti-bot-detector-overhaul-v0-7-8.md`
for the full design rationale of the v0.7.8 overhaul.
