v0.6.6: docs.rs build fix
Changelog
All notable changes to this project are documented in this file.
The format is based on Keep a Changelog,
and this project adheres to Semantic Versioning.
[0.6.6] - 2026-06-05
Fixed
- docs.rs build failure (Build #3487310) caused by
#[doc(cfg(...))]becoming unstable- Removed
#[cfg_attr(docsrs, doc(cfg(feature = "chrome")))]fromsrc/lib.rs:70 - Root cause: in Oct 2025 the Rust team merged
doc_auto_cfgintodoc_cfg(rust-lang/rust#43781),
making#[doc(cfg(...))]require# on the crate root.
The build failed witherror[E0658]: #[doc(cfg)] is experimentalon nightly1.98.0. - The feature gating itself is preserved:
#[cfg(feature = "chrome")]still excludes
pub mod browserfrom default builds. The module-level docstring insrc/browser.rs
already documents the feature requirement explicitly. cargo doc --all-featuresandRUSTDOCFLAGS="--cfg docsrs" cargo doc --all-features
both pass without warning or error.
- Removed
[0.6.5] - 2026-06-05
Fixed
- MP-26 — Windows HANDLE cast broken in
windows-sys 0.59+(src/platform.rs:51-63)HANDLEmudou deisizepara*mut c_voidupstream (microsoft/windows-rs,raw-window-handle#171)- Substituído
handle != 0 && handle != usize::MAXpor!handle.is_null() && handle != INVALID_HANDLE_VALUE - Removidos casts inválidos
handle as isize(a assinatura moderna aceitaHANDLEdireto) - Atualizado o
// SAFETY:comment para documentar nulidade e sentinela Win32
- CI:
validatefalhava em todos os 3 SOs (Linux/macOS/Windows) por 6 erros de clippy- 3×
clippy::doc_markdown(PowerShell,rules_rust.md,TempDir) emsrc/platform.rsesrc/browser.rs - 1×
clippy::needless_returnemsrc/browser.rs:149 - 2×
missing_debug_implementationsemsrc/browser.rs:223(ChromeBrowser) esrc/content_fetch.rs(CircuitBreakerMap)
- 3×
Added
- WS-11 — Property-based invariants for HTML parsers (
src/extraction.rs+5 testes)- Invariante: inputs vazios/quebrados retornam
Vecvazio sem panic - Invariante: positions são densos e 1-based
- Invariante: URLs absolutos (
http/https) ou vazios - Invariante: extração é idempotente
- Invariante: HTML malformado não causa panic
- Zero dependência nova (apenas stdlib +
#[test])
- Invariante: inputs vazios/quebrados retornam
- WS-12 — Per-host circuit breaker (
src/content_fetch.rs)- Threshold: 3 falhas consecutivas abrem o circuito
- Cooldown: 30s antes de half-open probe
- Integração em
enrich_with_contentantes de cada fetch BreakerDecision::{Allow, Reject}para inspeção- Zero dependência nova (
std::sync::Mutex<HashMap>)
- WS-23 —
Retry-Afterheader test (tests/integration_wiremock.rs)- Mock retorna 429 com
retry-after: 2 - Asserção:
elapsed_ms >= 1500(delay mínimo respeitado) - Usa
wiremock0.6 já em dev-deps
- Mock retorna 429 com
- WS-25 —
indicatifProgressBar para crawls longos (src/content_fetch.rs)indicatif = "0.18"adicionado- Bar com template
[{elapsed_precise}] {bar:40.cyan/blue} {pos:>4}/{len:4} {msg} - Auto-detecta TTY (esconde em pipes)
progress.finish_and_clear()ao final
- Lints preventivos FFI (
Cargo.toml)improper_ctypes = "deny"(rejeita casts FFI inválidos)improper_ctypes_definitions = "deny"(rejeita definições incorretas)
Tests
- 333 testes passando (243 lib + 24 + 3 + 5 + 10 + 10 + 14 + 18 + 6 doc)
- 6 novos testes de invariantes em
extraction.rs(WS-11) - 4 novos testes de circuit breaker em
content_fetch.rs(WS-12) - 1 novo teste de Retry-After em
integration_wiremock.rs(WS-23) cargo fmt --all --checkcleancargo clippy --all-targets --all-features --locked -- -D warningscleancargo publish --dry-run --locked --allow-dirtyclean
[0.6.4] - 2026-06-03
Added
- WS-26 — Adaptive anti-bot identity rotation (new
src/identity.rsmodule)- 12-identity pool (4 browser families × 3 platforms) for adaptive rotation
IdentityProfile::shuffled_headers()produces seed-deterministic header orderIdentityPool::rotate_on_block()implements a 5-level cascade: same identity → same family/different platform → different family/same platform → different family+platform → randomBrowserFamilyandPlatformenums with canonical English names- 5 unit tests covering pool size, cascade level, determinism, header shape, tag stability
- New CLI flags (additive, no breaking changes)
--probe— pre-flight health check (sends 1 minimal request, reports status/latency/Set-Cookie as JSON)--identity-profile— pin the session to a specific identity (auto,chrome-win,chrome-mac,chrome-linux,edge-win,firefox-linux,safari-mac).autois default.
- New JSON metadata fields (additive,
Option+skip_serializing_if = "Option::is_none")metadados.identidade_usada— string tag of the identity that produced the responsemetadados.nivel_cascata— cascade level reached during the request
Changed
- Version rollback:
0.7.0(unpublished) →0.6.4to preserve the in-development feature set under a stable patch number - All existing CLI flags, JSON output schemas, and exit codes remain unchanged — strictly additive changes
Tests
- 5 new identity unit tests (313 total tests passing, up from 308)
- All 224 lib tests + 83 integration tests + 6 doc tests pass
cargo clippy --lib --bins -- -D warningscleancargo fmt --checkclean
[0.7.0] - 2026-06-01
Changed
- Complete internationalization: ~600 identifiers renamed PT→EN across 15 source files (struct fields, local variables, parameters, production functions, test functions)
- Module
fetch_conteudorenamed tocontent_fetch - Test files
integracao_*.rsrenamed tointegration_*.rs - Replaced
anyhowwith typedCliErroracross all 11 modules — zero external error crate dependency output.rs: all formatting functions renamed (formatar_*→format_*,escrever_*→write_*)config_init.rs: struct fields renamed with#[serde(rename)]to preserve JSON backwards compatibilitysearch.rs:RetryResultandAggregatedSearchResultfields renamed PT→ENtypes.rs:Configfieldsperfil_browser/corresponde_plataforma_ua/caminho_chrome→browser_profile/match_platform_ua/chrome_path
Added
- Loom concurrency tests (
tests/loom_atomics.rs) — validatesAtomicBoolvisibility across threads - Criterion benchmarks (
benches/extraction_bench.rs) — HTML extraction performance baselines - Doc comments for all 70 previously undocumented public items — zero
missing_docswarnings .ingest-queue.sqliteadded to.gitignoreandCargo.tomlexclude
Fixed
- RUSTSEC-2026-0097: updated
rand0.8.5 → 0.8.6 - RUSTSEC-2026-0104: updated
rustls-webpki0.103.12 → 0.103.13
Security
deny.toml: addedskip-treefor 30 transitive duplicate crates (chromiumoxide, scraper, console-subscriber ecosystems)
Known Limitations
- Loom tests require
RUSTFLAGS="--cfg loom"which conflicts withhyper-util— tests compile but cannot run until upstream resolves the cfg conflict - JSON output field names remain in Portuguese Brazilian (
posicao,titulo,resultados, etc.) — BY DESIGN since v0.2.0
[0.6.3] - 2026-04-17
Changed
- Translated all 96 doc comments (
///and//!) across 19 source files from Portuguese to English — docs.rs now renders fully in English for international crates.io audience. - No code behavior, public API, or JSON output fields changed.
[0.6.2] - 2026-04-17
Added
- 19 novos arquivos de documentação — conformidade completa com rules_rust_documentacao.md (28 gaps G01-G28)
- Documentação bilíngue EN+PT: HOW_TO_USE, CROSS_PLATFORM, AGENTS-GUIDE, COOKBOOK.pt-BR, INTEGRATIONS.pt-BR
- CODE_OF_CONDUCT.md + CODE_OF_CONDUCT.pt-BR.md — Contributor Covenant 2.1
- README.pt-BR.md, CHANGELOG.pt-BR.md, CONTRIBUTING.pt-BR.md, SECURITY.pt-BR.md
- docs/AGENTS.pt-BR.md — guia imperativo para LLMs em português
- docs/AGENTS-GUIDE.md + docs/AGENTS-GUIDE.pt-BR.md — guia persuasivo bilíngue
- llms.txt — arquivo compacto de orientação para LLMs (< 50 KB)
- llms-full.txt — concatenação completa de docs para contexto longo de LLMs
- eval-queries.json × 2 — 20 queries de avaliação EN + 20 PT-BR para skill testing
Changed
- README.md — link para README.pt-BR.md + quick install antes da linha 30
- CONTRIBUTING.md — MSRV Rust 1.75 explícito + PR checklist 8 itens + branching strategy + nextest
- SECURITY.md — tabela de versão específica v0.6.2 + política de embargo 90 dias + zero bold + zero emojis
- skill/SKILL.md (EN+PT) — seção Workflow com 5 passos numerados verificáveis
[0.6.1] - 2026-04-17
Fixed
--timeout 0now returns exit 2 (invalid config) instead of executing a search with zero timeout and returning exit 5.--output /tmp/../../etc/passwdnow returns exit 2 (invalid config) instead of exit 1 (runtime OS error) — path traversal validation moved tomontar_configuracoes(), before the pipeline starts.
Added
validar_timeout_segundos()method onCliArgs— rejects values of 0 with a descriptive error.- Early path traversal check in
montar_configuracoes()— callspaths::validate_output_path()at config validation time, not at write time. - 2 E2E regression tests:
timeout_zero_retorna_exit_2andoutput_com_path_traversal_retorna_exit_2. - 1 unit test:
validar_timeout_segundos_rejeita_zero.
[0.6.0] - 2026-04-16
Security
- Browser fingerprint profiles per-family previnem detecção anti-bot do DuckDuckGo.
- Headers
Sec-Fetch-*e Client Hints por família imitam sessão de navegador real. Accept-Languagecom q-values RFC 7231 elimina fingerprint de UA genérico.- Detecção de bloqueio silencioso com limiar de 5 KB previne resultados truncados.
Added
BrowserFamilyenum — variantesChrome,Firefox,Edge,Safari.BrowserProfilestruct — encapsula família, versão e conjunto de headers por família.- Headers
Sec-Fetch-Dest,Sec-Fetch-Mode,Sec-Fetch-Sitepor família emhttp.rs. - Client Hints (
Sec-Ch-Ua,Sec-Ch-Ua-Mobile,Sec-Ch-Ua-Platform) para Chrome e Edge. - Detecção de HTTP 202 anomaly em
search.rscom backoff exponencial automático. - Detecção de bloqueio silencioso — resposta com menos de 5 000 bytes é tratada como bloqueio.
BrowserProfilepropagado viaConfigpara todos os módulos da pipeline.- Headers de paginação com
Sec-Fetch-Site: same-originpara imitar navegação real.
Changed
Accept-Languageatualizado parapt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7conforme RFC 7231.Acceptheader agora reflete o perfil completo do browser por família.- Delays de paginação aumentados de 500–1 000 ms para 800–1 500 ms.
- Limiar de bloqueio silencioso aumentado de 100 para 5 000 bytes.
[0.5.0] - 2026-04-16
Security
- Path traversal validation on
--output— rejects..components and writes to system directories (/etc,/usr,C:\Windows). - Proxy credential masking — error messages no longer expose passwords from
--proxy http://user:pass@hostURLs.
Added
src/paths.rs— centralized path validation, parent directory creation, and Unix permission application.src/signals.rs— centralized SIGPIPE restoration (Unix) and Ctrl+C/SIGINT handler (cross-platform).ErroCliDdgenum withthiserror— 11 typed error variants withexit_code()andcodigo_erro()methods.mascarar_url_proxy()inhttp.rs— redacts credentials from proxy URLs in error context.- 21 new unit tests across
paths.rs,signals.rs,error.rs, andhttp.rs.
Changed
thiserror = "2"added to dependencies for structured domain errors.src/main.rsreduced from 63 to 23 lines — signal handling extracted tosignals.rs.src/output.rsfile writes now validate paths viapaths::validate_output_path()before I/O.deny.tomlupdated with RUSTSEC-2026-0097 exception (rand 0.8 unsound with custom logger — not applicable).
[0.4.4] - 2026-04-16
Fixed
- SIGPIPE restored to SIG_DFL on Unix — pipes to
jaq,head, and other consumers no longer lose stdout silently. - BrokenPipe errors detected in anyhow chain and treated as exit 0 (not exit 1) at all output boundaries.
Added
--helpnow shows EXIT CODES (0–5) and PIPE USAGE sections viaafter_long_help.- 3 E2E tests for pipe regression: exit codes in help, short help exclusion, stdout byte count.
- README troubleshooting item 7: "Pipe to jaq/jq returns empty" with PIPESTATUS diagnostic (EN + PT).
docs_rules/rules_rust.md: SIGPIPE + BrokenPipe added to I/O checklist.docs/AGENT_RULES.md: R24 pipe safety rule with PIPESTATUS diagnostic.docs/COOKBOOK.md: Recipe 16 pipe diagnostic (EN + PT).docs/INTEGRATIONS.md: pipe safety clause in baseline contract.- Exit code branching section in both skill files (EN + PT).
[0.4.3] - 2026-04-15
Changed
README.md— Nova seção persuasiva "Agent Skill" (EN + PT) posicionada
entre a tabela de agentes e a seção de Documentação, no pico de atenção do
leitor. Copywriting AIDA destacando a skill bilíngue empacotada emskill/:
auto-ativação semântica sem slash command, 14 seções canônicas MUST/NEVER,
contrato JSON anti-alucinação, economia de tokens em cada turno de busca,
instalação em um comando (git clone+cp -r). Benefícios explícitos para
LLMs (decisão automática de quando buscar) e desenvolvedores (zero prompt
engineering, zero tool registration). Tarball do crates.io inalterado —
skills continuam vivendo apenas no GitHub.
[0.4.2] - 2026-04-15
Added
skill/duckduckgo-search-cli-pt/SKILL.mde
skill/duckduckgo-search-cli-en/SKILL.md— Skills bilíngues para Claude
Code, Claude Agent SDK e plataformas compatíveis com Agent Skills. Cada
skill traz frontmatter YAML comnameúnico por idioma edescription
carregado de triggers semânticos para auto-invocação, além de 14 seções
H2 canônicas (Missão, Contrato de Invocação, Proibições Absolutas,
Parsing comjaq, Schema JSON, Exit Codes, Batch, Fetch-Content,
Endpoint, Retries, Receitas, Validação, Memória, Regra de Ouro).
Publicadas no GitHub, excluídas do tarball do crates.io.
Changed
docs/AGENT_RULES.md(833 linhas, +7,6%) — Reescrita editorial
aplicando copywriting AIDA: cada regra abre com benefício mensurável,
linguagem imperativa MUST/NEVER reforçada, zero narrativa decorativa,
zero negrito com asteriscos duplos, zero separador visual---entre
seções. Bilíngue EN+PT espelhado com tom idêntico.docs/COOKBOOK.md(1082 linhas, −3,1%) — Cada receita abre com o
ganho concreto antes do comando, bullets curtos de 8 a 15 palavras,
pipelinesjaq+xh+sdpreservados intactos.docs/INTEGRATIONS.md(1212 linhas, +1,3%) — 16 agentes com tabela
comparativa textual, snippets determinísticos por agente, zero emoji.
Meta
Cargo.tomlexclude ampliado para cobrirskill/eskill/**— skills
ficam no GitHub e fora do tarball publicado em crates.io.
[0.4.1] - 2026-04-14
Added
docs/AGENT_RULES.md(773 linhas) — Regras imperativas bilíngue (EN+PT)
com 30+ rulesMUST/NEVER(R01..R30) para LLMs/agentes invocarem a CLI
em produção. Cobre: invariantes core, contrato JSON, rate limiting, error
handling, performance, segurança, anti-patterns. Quick Reference Card no
final.docs/COOKBOOK.md(1117 linhas) — 15 receitas copy-paste bilíngue
combinandoduckduckgo-search-cli+jaq+xh+sdpara casos reais:
research consolidado, ETL multi-query, extração de domínios, monitoramento
com filtro temporal, content extraction com--fetch-content, comparação
top 5 vs top 15, NDJSON para pipelines, function wrappers para bash.docs/INTEGRATIONS.md(1196 linhas) — Snippets prontos para 16
agentes/LLMs: Claude Code, OpenAI Codex, Gemini CLI, Cursor, Windsurf,
Aider, Continue.dev, MiniMax, OpenCode, Paperclip, OpenClaw, Google
Antigravity, GitHub Copilot CLI, Devin, Cline, Roo Code. Cada agente
documenta: pitch, mecanismo de shell, setup, snippet básico, snippet
multi-query, system prompt rule, caveats.- Seção Documentation no README.md (EN + PT) linkando os 3 guias.
Fixed
- README.md badge cluster e referências internas conferidas contra
daniloaguiarbr/duckduckgo-search-cli(repo canônico).
[0.4.0] - 2026-04-14
Changed (BREAKING)
- Default de
--num/-n: alterado de "todos os resultados da primeira
página" (~11) para 15, com auto-paginação automática. Quando o
número efetivo excede 10, o binário agora busca 2 páginas por query
para satisfazer o teto solicitado, desde que--pagesnão tenha sido
customizado pelo usuário. - Auto-paginação automática: se
--num > 10(seja porque o usuário
passou explicitamente ou porque o default 15 foi aplicado) E--pages
não foi customizado (continua no default 1), o binário auto-eleva
--pagesparaceil(num/10)respeitando o teto de 5 páginas validado
porvalidar_paginas. Impacto: mais requests por query (2x no caso
default) e latência marginalmente maior, porém com cobertura completa
dos resultados solicitados.
Added
- Documentação no comentário do flag
--numemcli.rsdescrevendo a
nova semântica de default e auto-paginação. - 4 novos testes unitários em
lib.rs::testes:
montar_configuracoes_aplica_default_num_15_quando_omitido,
montar_configuracoes_respeita_pages_explicito_acima_de_1,
montar_configuracoes_auto_pagina_quando_num_maior_que_10,
montar_configuracoes_nao_auto_pagina_quando_num_10_ou_menos. - 2 novos testes wiremock em
tests/integracao_wiremock.rs:
testa_default_num_15_auto_pagina_2_paginas,
testa_auto_paginacao_respeita_pages_explicito.
Migration Guide
- Quem quer o comportamento antigo (1 página, ~11 resultados):
passe--pages 1 --num 10explicitamente. O--pages 1explícito é
indistinguível do default (trade-off aceito:paginas > 1é o único
sinal de "customização"), então o mais seguro é combinar com--num 10
para garantir que nada será auto-paginado. - Quem já passava
--num 5(ou qualquer valor <= 10): comportamento
inalterado (sem auto-paginação, 1 página). - Quem já passava
--num 20 --pages 2ou similar: comportamento
inalterado (respeita explícito do usuário). - Quem confiava no default sem flags: agora recebe até 15 resultados
em vez de ~11, com 1 request extra por query. Para restaurar o antigo,
passe--pages 1 --num 10.
[0.3.0] - 2026-04-14
Changed (BREAKING)
- Schema JSON: campo
buscas_relacionadasREMOVIDO deSearchOutpute
MultiSearchOutput.buscas[i]. O endpointhtml.duckduckgo.com/html/não
expõe related searches no DOM atual; manter o campo sempre vazio era ruído.
Pipelines que parseavam.buscas_relacionadasprecisam ajuste. - Pool de User-Agents: removidos UAs de browsers de texto (
Lynx 2.9.0,
w3m/0.5.3,Links 2.29,ELinks 0.16.1.1) que faziam DuckDuckGo retornar
HTML degradado. Substituídos por 6 UAs modernos validados empiricamente
contra o/html/endpoint: Chrome 146 (Win/Mac/Linux), Edge 145 Windows,
Firefox 134 Linux, Safari 17.6 macOS. Firefox Win/Mac foram REMOVIDOS após
retornarem HTTP 202 anomaly em validação real (heurística anti-bot do DDG).
Fixed
- Snippet duplicava título e URL no início: o seletor padrão tinha
fallback.result__body(container pai) que faziatext()recursivo
capturar título+URL+snippet concatenados. Trocado por.result__snippet
puro. Pipelines comojaq '.resultados[].snippet'agora retornam apenas
o texto descritivo do resultado. - Título "Official site": DuckDuckGo renderiza literalmente este texto
como label para domínios verificados (ex: prefeituras). O scraper agora
detecta este caso e substitui pelourl_exibicao(ex:saofidelis.rj.gov.br).
O texto original é preservado no novo campo opcionaltitulo_original
para auditoria.
Added
- Campo
titulo_original: Option<String>emSearchResult. Presente
apenas quando o título foi substituído por heurística (atualmente: caso
"Official site"). Serializado com#[serde(skip_serializing_if = "Option::is_none")]
— não aparece no JSON quando ausente. - Resultados patrocinados (
.result--ad) excluídos do container default
via seletor.result:not(.result--ad).
Removed
- Função
extrair_buscas_relacionadasemsrc/search.rs(dead code com
seletor hardcoded que nunca encontrava nada). - Seção
[related_searches]em selectors default.
Migration Guide (v0.2.x → v0.3.0)
- Pipelines
jaq '.buscas_relacionadas[]': campo não existe mais.
Remover do filtro ou tratarnull. - Esperando snippet com prefixo título+URL? Agora vem só o texto descritivo
— ajuste regex/parsing downstream se necessário. - Confiando em
titulo == "Official site"para detectar sites verificados?
Usetitulo_original.as_deref() == Some("Official site"). - CONFIG EXTERNO LEGADO: usuários que rodaram
init-configem versões
anteriores possuem~/.config/duckduckgo-search-cli/{selectors,user-agents}.toml
com defaults antigos (snippet com.result__body+ UAsLynx/w3m/etc.).
Esses arquivos OVERRIDE os defaults embutidos. Para aplicar as correções
desta versão, execute APÓS atualizar:O flagduckduckgo-search-cli init-config --force--forcesobrescreve os arquivos externos. Backup recomendado se
você editou manualmente para hotfix de seletores.
[0.2.0] - 2026-04-14
Changed (BREAKING)
Schema JSON serializado agora usa nomes de campo em português brasileiro,
alinhado com os exemplos jaq do README e com o invariante INVIOLÁVEL do
blueprint v2 do projeto ("Logs e nomes de campo em português brasileiro").
Pipelines que dependiam do schema em inglês da v0.1.0 precisam atualizar
os seletores jaq. Tabela de renomeações:
| Antes (v0.1.0) | Depois (v0.2.0) |
|---|---|
position |
posicao |
title |
titulo |
displayed_url |
url_exibicao |
content |
conteudo |
content_length |
tamanho_conteudo |
content_extraction_method |
metodo_extracao_conteudo |
execution_time_ms |
tempo_execucao_ms |
selectors_hash |
hash_seletores |
retries |
retentativas |
fallback_endpoint_used |
usou_endpoint_fallback |
concurrent_fetches |
fetches_simultaneos |
fetch_successes |
sucessos_fetch |
fetch_failures |
falhas_fetch |
chrome_used |
usou_chrome |
proxy_used |
usou_proxy |
engine |
motor |
region |
regiao |
results_count |
quantidade_resultados |
results |
resultados |
related_searches |
buscas_relacionadas |
pages_fetched |
paginas_buscadas |
error |
erro |
message |
mensagem |
metadata |
metadados |
queries_count |
quantidade_queries |
parallel |
paralelismo |
searches |
buscas |
Campos inalterados: url, snippet, query, endpoint, timestamp, user_agent.
Fixed
- Pipelines documentados no README (
jaq '.resultados[].titulo', etc.) agora
funcionam end-to-end. Emv0.1.0retornavamnullpor divergência do schema
(bug reportado pelo usuário).
Unreleased
Added
LICENSE-MITandLICENSE-APACHE(dual-licensed perCargo.toml, aligning the tarball with the SPDX declaration)..pre-commit-config.yamlwith three hook groups: (1) pre-commit-hooks standard (trailing whitespace, EOF, YAML/TOML validity, mixed line endings), (2) Rust hooks (cargo fmt+cargo clippy -D warnings), (3) localcommit-msghook blockingCo-authored-by:from AI agents (mirrors the CIcommit_checkjob). Reduces CI round-trips for trivial violations..gitattributesforcing LF on.rs/.toml/.sh/.yml/.md/ fixture HTML — prevents silent corruption when cloning on Windows withcore.autocrlf=true(which would otherwise break shebangs, rustfmt, and content-extraction tests). Binary extensions (.png,.woff2, etc.) marked explicitly.Cargo.lockandtarget/flaggedlinguist-generatedto exclude from GitHub language stats..editorconfignormalizing UTF-8, LF, trailing-whitespace trim, and per-language indent (Rust/TOML 4, YAML/JSON/MD 2, Makefile tab) across VS Code, RustRover, vim, and other editors — eliminates spurious formatting diffs caused by per-dev settings drift..github/PULL_REQUEST_TEMPLATE.mdwith the 10-gate checklist + project-specific constraints (no cache, no MCP, rustls-only,println!confined tooutput.rs, PT-BR identifiers)..github/ISSUE_TEMPLATE/bug_report.yml+feature_request.yml+config.yml— structured triage with platform dropdown (glibc/musl/NixOS/Flatpak/Snap/macOS ARM/macOS Intel/Windows/WSL), install method, and constraint verification.config.ymlredirects security reports to Security Advisories and usage questions to Discussions.Cross.tomlenablingcross build --target <t>for ARM64/ARMv7 Linux targets (musl + glibc + hard-float) from any x86_64 host with Docker/Podman — complements the native CI pipeline for developers without a GitHub Actions runner.CONTRIBUTING.mdwith the 10-gate validation matrix, coding standards (Brazilian Portuguese identifiers, rustls-only TLS,output.rsas the soleprintln!site), three-layer testing strategy, supply-chain guardrails, and the tag-driven release process..cargo/config.tomlexposing 8 developer aliases (cargo check-all,cargo lint,cargo docs,cargo test-all,cargo cov,cargo cov-html,cargo publish-check,cargo pkg-list) — each mirrors a CI job for local reproduction.- Doctests in public API:
pipeline::combine_and_dedup_queries,content_fetch::extract_host, andsearch::format_kl— compilable examples on docs.rs that double as regression tests. SECURITY.mddocumenting the private-disclosure workflow via GitHub Security Advisories, response SLA (72 h), scope (HTTP/HTML parsing, credential leaks, path traversal, TLS) and security design assumptions (stateless, rustls-only, no JS for search)..github/dependabot.ymlenabling weekly automatic dependency updates for bothcargoandgithub-actionsecosystems, with semantic grouping (dev-deps, tokio-ecosystem, tracing-ecosystem) and PR count limits.rust-toolchain.tomlpinningstablewithrustfmt+clippycomponents for reproducible dev/CI builds..github/workflows/release.ymltriggered byv*.*.*tags (andworkflow_dispatchwithdry_run) running the 5-stage release pipeline perrules_rust.md§19: validate → build_matrix (5 targets) → macos_universal (lipo) → github_release (with generated notes) → crates_io (publish gated onCRATES_IO_TOKENsecret).msrvjob inci.ymlextractingrust-versionfromCargo.tomland runningcargo checkon that toolchain to detect MSRV drift on every PR..github/workflows/ci.ymlenforcing the 10-gate validation matrix across Ubuntu, macOS, and Windows:cargo check/clippy -D warnings/fmt --check/doc -D warnings/test --all-featureson all three OSes.cargo llvm-cov --fail-under-lines 80dedicated job on Ubuntu.cargo audit+cargo deny check advisories licenses bans sourcessupply-chain gate.cargo publish --dry-run+cargo package --listsensitive-file guard.- Static musl binary smoke test (
x86_64-unknown-linux-musl) covering Alpine Linux and minimal containers. commit_checkjob blockingCo-authored-by:trailers from AI agents in PRs.
deny.tomlwith full four-axis supply-chain policy (advisories/licenses/bans/sources) and documented ignores for three transitive unmaintained advisories (RUSTSEC-2025-0057 fxhash,RUSTSEC-2025-0052 async-std,RUSTSEC-2026-0097 rand) with justification and revisit notes.- 22 new tests raising coverage from 77.4% to 86.4% (lines):
tests/integration_pipeline.rs(10),tests/integracao_fetch_conteudo.rs(3), and 9 inline tests foroutput.rscoveringemit_ndjson,emit_stream_text,emit_stream_markdown, and thePipelineResultvariants viatempfile.
Changed
parallel.rscoverage 50% → 81%;pipeline.rs55% → 82%;content_fetch.rs68% → 85%;output.rs70% → 87%.
0.1.0 - 2026-04-14
Added
- Core search pipeline against DuckDuckGo HTML endpoint via pure HTTP (
html.duckduckgo.com/html/). - Lite endpoint fallback via
--endpoint litefor JavaScript-less pages. - Multi-query mode with automatic deduplication, positional args,
--queries-file, and stdin. - Parallel fan-out of queries with
--parallel(1..=20), bounded bytokio::JoinSet+Semaphore. --pages(1..=5) to collect multiple result pages per query.--fetch-contentfetches each result URL via pure HTTP, applies readability, and embeds the cleaned text in the JSON output.--max-content-length(1..=100_000) truncates extracted content respecting word boundaries.- Chrome headless fallback under
--features chromewith cross-platform detection (Linux including Flatpak/Snap, macOS including Apple Silicon, Windows including registry paths) and stealth flags (--disable-blink-features=AutomationControlled,--window-size=1920,1080,--no-first-run, platform-specific--no-sandbox,--disable-gpu). --chrome-pathflag to manually specify the Chrome/Chromium executable.--proxy URL+--no-proxy(HTTP/HTTPS/SOCKS5) with precedence over env vars.--global-timeout(1..=3600 s) wraps the whole pipeline intokio::time::timeout.--per-host-limit(1..=10) rate-limits fetches per host via a per-hostSemaphoremap.--match-platform-uanarrows the user-agent pool to the current platform.--streamNDJSON mode emits one result per line as they are extracted.- Four output formats:
json(default),text,markdown,auto(TTY-aware). - External configuration files:
selectors.tomlanduser-agents.tomlunder XDG config dir, overriding embedded defaults. - Subcommand
init-configwith--forceand--dry-runto bootstrap user config files. - Exit codes:
0success,1runtime,2config,3block (HTTP 202 anomaly),4global timeout,5zero results. - UTF-8 console initialization on Windows via
SetConsoleOutputCP(65001). - Rustls-TLS everywhere for dependency-free cross-platform builds.
tracing+tracing-subscriberwithRUST_LOGhonored;--verbose/--quietflags.- 163 unit + integration tests covering CLI parsing, config montage, HTTP extraction, parallel fan-out, selectors, and wiremock-backed search flows.
Security
- All credentials (
--proxy user:pass@host) are masked in logs. - Output file creation applies Unix permissions
0o644.
Full Changelog: v0.6.5...v0.6.6