Skip to content

feat(woot): add woot#1420

Open
TheFabulousMoolah wants to merge 2 commits into
mvanhorn:mainfrom
TheFabulousMoolah:feat/woot
Open

feat(woot): add woot#1420
TheFabulousMoolah wants to merge 2 commits into
mvanhorn:mainfrom
TheFabulousMoolah:feat/woot

Conversation

@TheFabulousMoolah

@TheFabulousMoolah TheFabulousMoolah commented Jul 2, 2026

Copy link
Copy Markdown

woot

Discovered API spec for Woot's browser-facing GraphQL endpoint and adds a read-only CLI for searching current Woot deals.

API: woot | Category: commerce | Press version: 4.27.1
Spec: spec.yaml

Publication Path

New print

CLI Shape

$ woot-pp-cli --help
Manage woot resources via the woot API.

Add --agent to any command for JSON output + non-interactive mode.
Run 'woot-pp-cli doctor' to verify auth and connectivity.

Usage:
  woot-pp-cli [command]

Available Commands:
  agent-context Emit structured JSON describing this CLI for agents
  api           Browse all API endpoints by interface name
  auth          Manage authentication for Woot
  completion    Generate the autocompletion script for the specified shell
  deals         List current Woot All Deals offers and optionally filter by keyword
  doctor        Check CLI health
  export        Export data to JSONL or JSON for backup, migration, or analysis
  feedback      Record feedback about this CLI (local by default; upstream opt-in)
  graphql       Run a read-only Woot GraphQL query
  help          Help about any command
  profile       Named sets of flags saved for reuse
  search        Search locally synced data
  sync          Sync API data to local SQLite for offline search and analysis
  version       Print version
  which         Find the command that implements a capability
  workflow      Compound workflows that combine multiple API operations

Novel Commands

Command Name Description
deals Woot All Deals Search Scan Woot's paged All Deals results and filter live offers by keyword.

What This CLI Does

deals uses the same frontend searchOffers GraphQL call as Woot's All Deals page, then filters titles, slugs, and item attributes locally. It can also reuse category, price, and page filters from a copied /alldeals URL.

The generated graphql command now sends a small read-only default query and rejects mutation/subscription documents for custom --query input.

Manuscripts

Validation Results

Check Result
Manifest PASS
Transcendence PASS
Phase 5 PASS
go mod tidy PASS
govulncheck (this CLI only, reachable findings) PASS
go vet PASS
go build PASS
--help PASS
--version PASS
verify-skill PASS
Package secret scan PASS

Publish Live Gate

Full live dogfood passed with a fresh phase5-acceptance.json: 38 passed, 27 skipped, 0 failed.

Additional live proof runs woot-pp-cli deals rayon --limit 10000 --agent; it returned 9 live results and included the target Woot URL/title for 8Pk Asst Mens S/S Rayon Tees.

Public Safety Review

An adversarial review initially found path-leaking detailed dogfood output, missing proof for the Woot-specific deals command, and read-only GraphQL enforcement risk. Those were fixed before push:

  • Removed path-bearing publish-live-gate.json from shipped proofs.
  • Added compact deals-live-proof.json.
  • Rejected mutation/subscription GraphQL documents.
  • Replaced local-build README examples with installed CLI examples.
  • Set manifest spec_path to packaged spec.yaml.

Re-check found no public blockers. Exact captured key scan over the committed publish tree returned zero matches.

@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a new read-only CLI (woot-pp-cli) for Woot's browser-facing GraphQL API, generated by CLI Printing Press and enriched with a novel deals command that scrapes the searchOffers GraphQL endpoint.

  • deals command fetches Woot All Deals via the same frontend searchOffers GraphQL call, paginates automatically up to --limit, and filters results locally by keyword, category, price range, and sort mode. A --from-url shortcut parses filters directly from a copied /alldeals URL.
  • graphql command adds a read-only smoke-test path and enforces that custom --query input does not contain mutation or subscription operations via a depth-aware token scanner (containsGraphQLWriteOperation).
  • All query-building paths sanitize inputs with safeGraphQLString/safeGraphQLEnum validators and parse price ranges strictly via strconv.ParseFloat, making injection into the constructed GraphQL document infeasible with current inputs.

Confidence Score: 5/5

Safe to merge; the change is entirely additive, read-only, and well-tested with live dogfood evidence.

All query-building paths sanitize inputs before GraphQL interpolation, the host-validation fix from the earlier review round is in place, and the write-operation guard uses correct depth tracking. No data is written to Woot, no existing code is modified, and the 90-file tree passes govulncheck, go vet, and a full phase-5 acceptance run.

No files require special attention; the novel logic in deals.go and promoted_graphql.go is the highest-risk surface and both look correct.

Important Files Changed

Filename Overview
library/commerce/woot/internal/cli/deals.go Novel deals command: pagination loop, query builder, URL-filter parser, and local keyword filter all look correct; inputs are validated before interpolation into the GraphQL string.
library/commerce/woot/internal/cli/promoted_graphql.go Depth-tracking containsGraphQLWriteOperation correctly avoids false positives on field names and string literals; tests cover the named-operation, comment, and second-operation cases.
library/commerce/woot/internal/client/client.go HTTP client with browser-impersonation (surf/enetx), adaptive rate limiting, credential-aware cache keying, auth header stripping on cross-host redirects, and a verify-mode short-circuit for mutating verbs.
library/commerce/woot/internal/cli/deals_test.go Covers URL parsing (happy path and lookalike-host rejection), bracket price-range parsing, and query-builder field inclusion; good baseline for the novel command.
library/commerce/woot/internal/cli/promoted_graphql_test.go Six table-driven cases for containsGraphQLWriteOperation; named-operation, comment/string ignoring, read-field named mutation, and second-operation cases all verified.
library/commerce/woot/manifest.json Manifest description still references the raw CloudFront distribution ID (d24qg5zsx8xdc4-cloudfront) rather than a human-readable name; functionally harmless but exposes internal infrastructure naming in the published artifact.
library/commerce/woot/internal/cli/auth.go Standard auth setup/status/set-token/logout commands; browser-launch safety guard checks IsVerifyEnv() before calling exec.Command.
library/commerce/woot/spec.yaml Minimal GraphQL-over-GET OpenAPI spec with a single /graphql path; matches the implementation.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant CLI as woot-pp-cli deals
    participant Parser as URL/Flag Parser
    participant Builder as buildWootDealsQuery
    participant Client as HTTP Client
    participant Woot as Woot GraphQL API

    User->>CLI: "deals [keyword] [--from-url | --category | --price-range | --page]"
    CLI->>Parser: parseWootAllDealsURL (if --from-url)
    Parser-->>CLI: categories, priceRanges, page (validated host suffix)
    CLI->>Parser: parseWootPriceRanges
    Parser-->>CLI: []wootPriceRange (numeric parse)

    loop "scanned < maxToScan (or single page)"
        CLI->>Builder: buildWootDealsQuery(categories, priceRanges, sortMode, limit, skip)
        Note over Builder: safeGraphQLEnum(sort) safeGraphQLString(category) formatGraphQLFloat(price)
        Builder-->>CLI: validated GraphQL query string
        CLI->>Client: "GetWithHeadersNoCache(ctx, /graphql, {query: ...})"
        Client->>Woot: "GET /graphql?query=..."
        Woot-->>Client: "JSON {data:{searchOffers:{Offers:[...], TotalHits:N}}}"
        Client-->>CLI: json.RawMessage
        CLI->>CLI: normalizeWootDeals (build URLs, compute price range)
        CLI->>CLI: check totalHits / batch size for early exit
    end

    CLI->>CLI: filterWootDeals(deals, keyword) — local substring match
    CLI-->>User: table / JSON output with meta envelope
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant CLI as woot-pp-cli deals
    participant Parser as URL/Flag Parser
    participant Builder as buildWootDealsQuery
    participant Client as HTTP Client
    participant Woot as Woot GraphQL API

    User->>CLI: "deals [keyword] [--from-url | --category | --price-range | --page]"
    CLI->>Parser: parseWootAllDealsURL (if --from-url)
    Parser-->>CLI: categories, priceRanges, page (validated host suffix)
    CLI->>Parser: parseWootPriceRanges
    Parser-->>CLI: []wootPriceRange (numeric parse)

    loop "scanned < maxToScan (or single page)"
        CLI->>Builder: buildWootDealsQuery(categories, priceRanges, sortMode, limit, skip)
        Note over Builder: safeGraphQLEnum(sort) safeGraphQLString(category) formatGraphQLFloat(price)
        Builder-->>CLI: validated GraphQL query string
        CLI->>Client: "GetWithHeadersNoCache(ctx, /graphql, {query: ...})"
        Client->>Woot: "GET /graphql?query=..."
        Woot-->>Client: "JSON {data:{searchOffers:{Offers:[...], TotalHits:N}}}"
        Client-->>CLI: json.RawMessage
        CLI->>CLI: normalizeWootDeals (build URLs, compute price range)
        CLI->>CLI: check totalHits / batch size for early exit
    end

    CLI->>CLI: filterWootDeals(deals, keyword) — local substring match
    CLI-->>User: table / JSON output with meta envelope
Loading

Reviews (2): Last reviewed commit: "fix(woot): address review feedback" | Re-trigger Greptile

Comment thread library/commerce/woot/internal/cli/deals.go Outdated
Comment thread library/commerce/woot/internal/cli/deals.go Outdated
Comment thread library/commerce/woot/internal/cli/promoted_graphql.go
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