Echo/Docs

CLI command

comparisons

Published comparisons of every product the Stado catalogue declares against its competitors, every claim quoting a captured page of the side it describes.

Invocation#

Shell
echo-cli comparisons products sync --by <name>
echo-cli comparisons products list
echo-cli comparisons competitors list --product <catalogue id>
echo-cli comparisons competitors add --product <catalogue id> --name <competitor> --pages <https-url,...> --by <name>
echo-cli comparisons competitors discover --product <catalogue id> --by <name>
echo-cli comparisons competitors remove --product <catalogue id> --competitor <slug> --by <name>
echo-cli comparisons list --product <catalogue id> [--competitor <slug>]
echo-cli comparisons write --product <catalogue id> --competitor <slug> --by <name>
echo-cli comparisons withdraw --id <version id> --by <name>
echo-cli comparisons refresh --by <name>

Inputs and output#

products sync writes { added, changed, retired, unchanged }, the catalogue ids in each; products list writes every stored product by id: id, name, description, visibility, catalogue_status, publishable, unpublished_reason (null when publishable), pages, synced_by, synced_at and retired_at. competitors list, add and remove write the competitor: id, product_id, slug, name, pages, origin (declared or discovered), evidence, rejected, created_by, created_at, rejected_by and rejected_at. competitors discover writes { product_id, status (saturated or incomplete), added, known, unresolved, source_errors }: the competitors kept, the slugs already stored, and each included competitor whose official website no search result verified, with the errors that said why. list, write and withdraw write comparison versions: id, product_id, competitor_slug, competitor_name, version, product_urls, competitor_urls, capture_ids, rows (dimension, ours and theirs, each null or { claim, capture_id, url, captured_at, quote }), dropped, published, hold_reason, route, created_by, created_at, withdrawn_by and withdrawn_at. refresh writes one outcome per product and competitor: product_id, competitor, written, unchanged, discovery and error.

State effect#

products sync runs `stado product catalog --json` (ECHO_STADO_BIN names another stado) and sends every product it prints; every other verb calls Echo Web's authenticated /api/market/comparisons with ECHO_INTERNAL_BEARER at ECHO_WEB_BASE_URL. The Published product comparisons section of the competitors screen and of Echo Desktop's GEO screen call the same operations, echo-mcp reads them as echo_product_comparisons, and /api/cron/product-comparisons runs refresh daily. A product the catalogue declares public is publishable; any other is stored with the reason, and a product that left the catalogue is retired, its comparisons withdrawn; a product added to the catalogue is stored on the next sync. A product's pages are https://<id>.<ECHO_PRODUCT_SITE_DOMAIN>/ and its /docs. discover runs competitors-cli discovery over Echo's web search and the ECHO_COMPARISON_ROUTE route, bounded by ECHO_COMPARISON_DISCOVERY_ROUNDS, ECHO_COMPARISON_SURFACE_QUERIES and ECHO_COMPARISON_SEARCH_TEXT_BYTES, and keeps a competitor only with an official website a search result it cites verified. write captures every page of both sides now through Weles, as competitors capture does, and asks ECHO_COMPARISON_ROUTE for rows; a side whose quote its capture does not hold is dropped and counted, and the version is published when both sides keep a cited claim, held with the reason otherwise. remove keeps the competitor as rejected, so discovery does not add it again, and withdraws its comparisons. refresh discovers competitors for a publishable product that has none, captures every page again and writes the next version only where a page's text changed or no version exists. The newest published, unwithdrawn version of each competitor is public at /compare/<product>/<competitor>, listed at /compare/<product> and /compare.

Refusals#

  • A wrong invocation is refused before anything is sent: "comparisons takes <every verb's usage, separated by semicolons>; got <word>", "comparisons products takes …", "comparisons competitors takes …", "comparisons <verb> does not take <flag>; it takes …", "<flag> needs a value" and "comparisons <verb> needs <flag>".
  • products sync is refused when Stado is: "<stado> product catalog --json refused (exit <n>): <Stado's own words>", "<stado> product catalog --json printed no JSON (<cause>)" or "<stado> product catalog --json printed no products list: <first line>".
  • Echo Web answers a bad request with "products is required: every product of the Stado catalogue, as a non-empty list", "products[<n>]: <field> is required, as stado product catalog --json prints it", "products names <ids> more than once; the catalogue holds each product once", "<id> is not published: the Stado catalogue declares <id> <visibility>, and only a public product's comparisons are published", "<id> left the Stado catalogue and was retired at <instant>; its comparisons are not published", "name is required: the competitor as its own pages name it", "pages is required: the public https pages of <name> its comparison quotes, as a non-empty list", "url must be an absolute https address; got <value>", "competitor <slug> of <id> was removed by <who> at <instant>; echo-cli comparisons competitors add declares it again", "id is required: the comparison version echo-cli comparisons list prints" or "<SETTING> must be a positive whole number of <unit>, not <value>".
  • Not found: "no catalogue product has id <id>; the last catalogue sync stored <ids> (echo-cli comparisons products sync stores the catalogue)", "<id> has no competitor <slug>; it has <slugs>", "no comparison version has id <id>; echo-cli comparisons list --product <id> lists them" and "<url> could not be read (<Weles's error>); capture <id> keeps the error". Conflicts: "<id> already has competitor <slug> (<name>, <origin> by <who>) reading <pages>", "competitor <slug> of <id> was already removed by <who> at <instant>" and "comparison <id> was already withdrawn by <who> at <instant>". The command prints Echo Web's sentence and exits 1.