Skip to content

Comments

fix(cli): correct market price labeling and status/comment filters#10

Open
morluto wants to merge 4 commits intoPolymarket:mainfrom
morluto:codex/fix-cli-market-comments-status-filters
Open

fix(cli): correct market price labeling and status/comment filters#10
morluto wants to merge 4 commits intoPolymarket:mainfrom
morluto:codex/fix-cli-market-comments-status-filters

Conversation

@morluto
Copy link

@morluto morluto commented Feb 24, 2026

Summary

This PR fixes three CLI behavior issues in Gamma-facing commands/output:

  1. markets list labeled the price column as "Price (Yes)" and always used the first outcome price, which is incorrect for non-binary or differently ordered outcomes.
  2. comments list --entity-type market was exposed by the CLI even though Gamma comments only accept Event/Series.
  3. --active was implicitly transformed into --closed in markets list and events list (active=false became closed=true), causing misleading filter behavior.

Problem Details

1) Market table outcome mismatch

The table output implied it always showed "Yes" while implementation used outcome_prices.first(). For markets like Long/Short, Dems/Reps, etc., the label and value mapping were wrong.

2) Comments entity type mismatch with API contract

The CLI enum included Market and mapped to ParentEntityType::Market, but Gamma returns 422 invalid entity type for that input.

3) Status filter coupling

Both markets and events list commands derived closed from active when closed was omitted. This collapsed two independent filters into one derived filter and changed query intent.

What Changed

Market output behavior

  • Renamed market list column from Price (Yes) to Price.
  • Added outcome-aware price selection:
    • Prefer the Yes outcome price when present (case-insensitive match).
    • Otherwise use the first outcome/price pair.
  • Render value as <Outcome>: <price in cents> (e.g. Yes: 52.00¢, Long: 58.43¢, Dems: 41.00¢).

Comments entity-type contract

  • Removed Market from CLI EntityType enum.
  • Removed EntityType::Market -> ParentEntityType::Market mapping.
  • Updated command docs/help text to event|series only.

Active/closed filter semantics

  • Removed the closed.or_else(|| active.map(|a| !a)) translation.
  • events list now passes active and closed independently to the request builder.
  • Both markets list and events list now apply independent status filtering in CLI logic via shared helper pattern:
    • flag_matches(value, filter)
    • apply_status_filters(items, active_filter, closed_filter)

This preserves expected behavior even if API-side status fields are inconsistent.

Tests Added

  • src/output/markets.rs
    • row_prefers_yes_outcome_when_not_first
    • row_uses_first_outcome_for_non_binary_market
    • Updated row_formats_price_as_cents
  • src/commands/comments.rs
    • entity_type_does_not_expose_market_variant
  • src/commands/markets.rs
    • status_filters_are_independent
    • active_filter_does_not_imply_closed_filter
  • src/commands/events.rs
    • status_filters_are_independent
    • active_filter_does_not_imply_closed_filter

Documentation

  • Updated README market table example to show Price and outcome-prefixed values.

Verification

Automated

  • cargo test
    • Result: pass (101 unit tests, 49 CLI integration tests)

Manual / Runtime against live API

  • markets list --limit 50
    • Confirms Price header and outcome-aware entries (Long: ..., Dems: ..., etc.)
  • comments list --help
    • Confirms possible values are now event, series
  • comments list --entity-type market ...
    • Fails at CLI argument parsing (no API call), as intended
  • markets/events --active false vs --closed true
    • Result sets are no longer treated as equivalent by CLI logic

Risk / Compatibility

  • User-visible output change: market table column/value format changed (Price + prefixed outcome label).
  • CLI argument surface change: comments list --entity-type market is now rejected at parse-time.
  • No changes to authenticated trading flows.

Changelog

  • fix(cli): make market list price outcome-aware and correctly labeled
  • fix(cli): restrict comments entity type to Event/Series
  • fix(cli): preserve independent active/closed semantics in events/markets list filters

Note

Medium Risk
User-visible behavior changes in listing filters and table output, plus a breaking CLI flag value removal for comments; low security impact but could affect scripts relying on prior semantics/output.

Overview
Fixes several Gamma-facing CLI inconsistencies around listing filters and output.

markets list table output now labels the column as Price and renders an outcome-aware primary price (prefers the Yes outcome when present, otherwise the first outcome), including the outcome name in the cell (e.g. Yes: 52.00¢); README examples and unit tests were updated accordingly.

comments list no longer exposes --entity-type market (event/series only), and events list/markets list stop deriving closed from active; instead, active and closed are treated as independent filters via a new shared flag_matches helper with added tests.

Written by Cursor Bugbot for commit 3c9cb35. This will update automatically on new commits. Configure here.

- Make market list price outcome-aware and rename column from Price (Yes) to Price\n- Restrict comments entity-type enum to Event/Series to match Gamma validation\n- Stop translating active into closed; apply active/closed filters independently in markets/events list\n- Add regression tests for outcome labeling and independent status filter behavior\n- Update README examples to match new market table output
@morluto
Copy link
Author

morluto commented Feb 24, 2026

Here is an explanation of the underlying issues this PR addresses.

Problem Overview

There were three separate but related correctness issues in the CLI:

  1. markets list rendered a column labeled "Price (Yes)" while always using outcome_prices.first().
  2. comments list --entity-type market was exposed by CLI argument parsing but rejected by Gamma (422 invalid entity type).
  3. --active and --closed filters were coupled in markets list and events list (active=false implied closed=true).

Each issue produced behavior that could look valid at a glance but was semantically wrong.

1) Market list price labeling/mapping bug

Root cause

The table output was hardcoded as Price (Yes) and took the first outcome price regardless of market schema/order.

Why this is incorrect

Not all markets are Yes/No. Many are Long/Short, team-vs-team, party-vs-party, etc. For those markets:

  • The label "Yes" is invalid.
  • The first outcome may not represent the logical “yes” side.

User impact

This can mislead users reading table output, especially when quickly scanning markets to make decisions. The value could be numerically accurate for index 0 but semantically mislabeled.

Fix approach

  • Rename the table column to Price.
  • Use outcome-aware selection:
    • Prefer Yes outcome (case-insensitive) when present.
    • Otherwise use first outcome/index pair.
  • Render explicit label/value in the table cell (e.g. Yes: 52.00¢, Long: 58.43¢, Dems: 41.00¢).

2) Comments entity type contract mismatch

Root cause

CLI exposed EntityType::Market and mapped it to SDK ParentEntityType::Market, but Gamma comments endpoint validates entity type as Event/Series only.

User impact

The CLI accepted input that could never succeed server-side, resulting in avoidable runtime failures.

Fix approach

  • Remove Market from CLI enum.
  • Remove Market mapping.
  • Update CLI help/docs to only allow event|series.
  • This shifts failure left to argument parsing and aligns CLI contract with API contract.

3) Active/closed filter coupling

Root cause

Both markets and events list commands derived closed from active when closed was omitted, effectively translating:

  • --active false -> closed=true
  • --active true -> closed=false

Why this is wrong

active and closed are separate dimensions in request semantics and should remain independent. Deriving one from the other changes user intent and can hide valid states.

User impact

Users asking for one status dimension unintentionally received results filtered by another. This produced surprising/inaccurate query behavior.

Fix approach

  • Stop deriving closed from active.
  • Pass explicit request filters independently.
  • Apply independent status matching in CLI post-filter logic to preserve intended semantics robustly.

Verification Summary

  • Added regression tests for:
    • outcome-aware market price selection/labeling,
    • comments entity type surface,
    • independent active/closed filtering in markets/events.
  • Full test suite passes.
  • Live CLI checks validate:
    • outcome-labeled Price output,
    • parser rejection of --entity-type market,
    • no implicit active <-> closed equivalence.

- Keep markets list filling up to --limit when --active is set by paginating additional API pages\n- Preserve independent active/closed semantics while avoiding undersized result pages\n- Move shared Option<bool> filter matcher into commands/mod.rs and reuse in events/markets\n- Add/retain tests and run full suite
@morluto
Copy link
Author

morluto commented Feb 24, 2026

Follow-up:

  • markets list now paginates/backfills when --active is set.
  • It fetches additional pages and applies status filtering client-side until either:
    • enough filtered rows are collected to satisfy --limit, or
    • the API has no more rows.
  • This avoids undersized responses caused by first-page-only filtering.
  • flag_matches was deduplicated.
  • Moved to shared mod.rs.
  • events.rs and markets.rs now both use the shared helper.

Verification:

  • cargo test passes (103 unit + 49 integration).
  • Live check: markets list --active true --limit 25 now returns 25 filtered rows in table/json flow.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

- Preserve market list price display when outcomePrices is present but outcomes is absent\n- Fallback to unlabeled first outcome price instead of rendering an em dash\n- Add regression test for outcomes-missing case
Return empty result when limit <= 0 before pagination to avoid forcing one-row output.
@morluto
Copy link
Author

morluto commented Feb 24, 2026

Follow-up fixes:
4ecd009: keep price visible when outcomePrices exists but outcomes is missing.
3c9cb35: preserve --limit 0 semantics in markets list (returns empty result).
Prior follow-up remains:
5949b79: active-filter backfill pagination + shared flag_matches.
Verification:
cargo test passes (104 unit + 49 integration).
Live check: markets list --limit 0 now returns 0 rows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant