Documentation
¶
Overview ¶
Package cli wires the kong grammar, the runtime, and the exit-code mapping. main() does nothing but os.Exit(cli.Run(...)) so every path is testable in-process.
Index ¶
- Constants
- func Run(args []string, stdin io.Reader, stdout, stderr io.Writer) int
- type AgentCmd
- type AuthCmd
- type AuthLoginCmd
- type AuthLogoutCmd
- type AuthRefreshCmd
- type AuthStatusCmd
- type BrowseCmd
- type CLI
- type DoctorCmd
- type ItemCmd
- type ItemCompareCmd
- type ItemGetCmd
- type ItemOffersCmd
- type ProviderCmd
- type ProviderListCmd
- type ReviewsCmd
- type Runtime
- type SchemaCmd
- type SearchCmd
- type VariationsCmd
- type VersionCmd
Constants ¶
const DefaultAssociateTag = "rivr-20"
DefaultAssociateTag is rivr's built-in Amazon Associates tag. When the user neither supplies their own (--associate-tag / RIVR_ASSOCIATE_TAG) nor opts out (--no-associate-tag), product deep links carry this tag.
What it does: if a referred link results in a purchase, Amazon pays the project a small referral fee. The buyer pays nothing extra. It funds rivr's development AND helps the project meet the Amazon Creators API's qualified-sales minimums (which gate official-API access). It is fully disclosed (visible in every URL, in `doctor`, in `schema`, and in the docs), replaceable with your own tag, and disablable.
This is the project's real registered Amazon Associates tag (US store; "-20" suffix).
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AuthCmd ¶
type AuthCmd struct {
Status AuthStatusCmd `cmd:"" help:"Test credentials and show auth status for the active provider."`
Login AuthLoginCmd `cmd:"" help:"Store a provider credential (read from stdin)."`
Logout AuthLogoutCmd `cmd:"" help:"Remove LOCAL credentials for a provider."`
Refresh AuthRefreshCmd `cmd:"" help:"Refresh the official backend's OAuth token."`
}
AuthCmd groups credential management. Secrets are read from STDIN, never argv (contract §7), and stored via internal/auth (env → OS keyring → 0600 file fallback).
type AuthLoginCmd ¶
type AuthLoginCmd struct{}
func (*AuthLoginCmd) Run ¶
func (c *AuthLoginCmd) Run(rt *Runtime) error
type AuthLogoutCmd ¶
type AuthLogoutCmd struct{}
func (*AuthLogoutCmd) Run ¶
func (c *AuthLogoutCmd) Run(rt *Runtime) error
type AuthRefreshCmd ¶
type AuthRefreshCmd struct{}
func (*AuthRefreshCmd) Run ¶
func (c *AuthRefreshCmd) Run(rt *Runtime) error
type AuthStatusCmd ¶
type AuthStatusCmd struct{}
func (*AuthStatusCmd) Run ¶
func (c *AuthStatusCmd) Run(rt *Runtime) error
type BrowseCmd ¶
type BrowseCmd struct {
NodeID string `arg:"" name:"node-id" help:"Browse-node id."`
}
BrowseCmd implements `rivr browse <node-id>` (read). Browse nodes are an official Creators-API feature; providers that lack it return UNSUPPORTED_BY_PROVIDER.
type CLI ¶
type CLI struct {
// Output (contract §1, §6)
Format string `enum:"json,plain,tsv" default:"plain" help:"Output format: json, plain, or tsv."`
JSON bool `help:"Shorthand for --format=json."`
NoColor bool `help:"Disable colored output."`
Limit int `default:"50" help:"Maximum items to return for list operations."`
Select string `help:"Comma-separated dot-path field projection, e.g. asin,title,price."`
Concise bool `help:"Terser output (default)."`
Detailed bool `help:"Richer output."`
// Backend (rivr-specific)
Provider string `help:"Backend provider (e.g. serpapi, rainforest, creators). Overrides the configured default." env:"RIVR_PROVIDER"`
AssociateTag string `` /* 142-byte string literal not displayed */
NoAssociateTag bool `` /* 148-byte string literal not displayed */
// Prompt-injection hardening (contract §8) — ON by default; --no-wrap-untrusted to disable.
WrapUntrusted bool `default:"true" negatable:"" help:"Fence attacker-controllable free text (titles, descriptions, reviews) as untrusted."`
// Safety (contract §2). rivr is read-only: these are present for contract uniformity
// but inert — no command performs a mutation.
AllowMutations bool `help:"Permit state-changing operations (no-op: rivr is read-only)."`
DryRun bool `help:"Print intended mutations without performing them (no-op: rivr is read-only)."`
Yes bool `help:"Assume yes for confirmations (no-op: rivr is read-only)."`
Force bool `help:"Bypass safety checks (no-op: rivr is read-only)."`
NoInput bool `help:"Never prompt; fail with exit 13 instead."`
// Commands (all reads)
Search SearchCmd `cmd:"" help:"Search Amazon products by keyword/category."`
Item ItemCmd `cmd:"" help:"Get product detail and offers."`
Reviews ReviewsCmd `cmd:"" help:"Get customer reviews for a product (third-party providers only)."`
Variations VariationsCmd `cmd:"" help:"List size/color/style variations of a product."`
Browse BrowseCmd `cmd:"" help:"Inspect the browse-node (category) tree."`
ProviderC ProviderCmd `cmd:"" name:"provider" help:"List and inspect configured backends."`
Auth AuthCmd `cmd:"" help:"Manage provider credentials."`
Doctor DoctorCmd `cmd:"" help:"Diagnose setup and report fixes."`
Schema SchemaCmd `cmd:"" help:"Print the machine-readable command schema (JSON)."`
Agent AgentCmd `cmd:"" help:"Print the bundled agent SKILL.md."`
Version VersionCmd `cmd:"" help:"Print the version."`
}
CLI is the kong grammar. Global flags are the universal agent-CLI contract surface plus rivr-specific --provider and --wrap-untrusted; subcommands follow noun-verb grammar.
type ItemCmd ¶
type ItemCmd struct {
Get ItemGetCmd `cmd:"" help:"Get full product detail for one or more ASINs."`
Offers ItemOffersCmd `cmd:"" help:"Get live offers / buybox / availability for an ASIN."`
Compare ItemCompareCmd `cmd:"" help:"Compare two or more ASINs side-by-side with a best-of summary."`
}
ItemCmd groups product-detail read subcommands.
type ItemCompareCmd ¶ added in v0.2.0
type ItemCompareCmd struct {
ASIN []string `arg:"" help:"Two or more product ASINs to compare."`
}
ItemCompareCmd implements `rivr item compare <asin...>` (read): fetch each ASIN and return them alongside a "best-of" summary (cheapest / highest-rated / most-reviewed), so an agent doesn't have to hand-assemble a comparison from N separate `item get` calls.
func (*ItemCompareCmd) Run ¶ added in v0.2.0
func (c *ItemCompareCmd) Run(rt *Runtime) error
type ItemGetCmd ¶
type ItemGetCmd struct {
ASIN []string `arg:"" help:"One or more product ASINs."`
}
ItemGetCmd implements `rivr item get <asin...>` (read).
func (*ItemGetCmd) Run ¶
func (c *ItemGetCmd) Run(rt *Runtime) error
type ItemOffersCmd ¶
type ItemOffersCmd struct {
ASIN string `arg:"" help:"Product ASIN."`
}
ItemOffersCmd implements `rivr item offers <asin>` (read).
func (*ItemOffersCmd) Run ¶
func (c *ItemOffersCmd) Run(rt *Runtime) error
type ProviderCmd ¶
type ProviderCmd struct {
List ProviderListCmd `cmd:"" help:"List configured backends and their capabilities."`
}
ProviderCmd groups backend-management read subcommands.
type ProviderListCmd ¶
type ProviderListCmd struct{}
ProviderListCmd implements `rivr provider list` (read).
func (*ProviderListCmd) Run ¶
func (c *ProviderListCmd) Run(rt *Runtime) error
type ReviewsCmd ¶
type ReviewsCmd struct {
ASIN string `arg:"" help:"Product ASIN."`
Cursor string `help:"Opaque pagination cursor from a previous nextCursor."`
}
ReviewsCmd implements `rivr reviews <asin>` (read). Review text is the sharpest prompt-injection vector — bodies/titles are always fenced. Not all backends serve it (the official Creators API returns no review text → UNSUPPORTED_BY_PROVIDER).
func (*ReviewsCmd) Run ¶
func (c *ReviewsCmd) Run(rt *Runtime) error
type Runtime ¶
type Runtime struct {
Cfg *CLI
Out *output.Writer
Stdin io.Reader
Ctx context.Context
// contains filtered or unexported fields
}
Runtime is the per-invocation context bound into every command's Run method.
func (*Runtime) Fence ¶
Fence wraps a free-text value as untrusted when --wrap-untrusted is on (contract §8).
func (*Runtime) Guard ¶
Guard enforces the read-only-by-default mutation gate (contract §2). rivr has no mutating commands, so this is never reached at runtime — kept for contract uniformity.
func (*Runtime) Link ¶
Link decorates a product deep link with the active Associates tag. The CLI is read-only; the deep link is its terminal hand-off to amazon.com (purchase happens in the user's browser session). By default the built-in project tag is used (see affiliate.go); a user tag replaces it, and --no-associate-tag disables it (with a one-time stderr notice). Non-product URLs (e.g. images) are not passed through here.
func (*Runtime) PartnerTag ¶
PartnerTag returns the tag to send to the official Creators API, which REQUIRES a partnerTag on every request. Unlike deep-link decoration, this can't be empty: a user tag wins, otherwise the built-in default (even when link-decoration is opted out).
type SearchCmd ¶
type SearchCmd struct {
Query string `arg:"" help:"Search keywords."`
Category string `help:"Restrict to a category / browse node."`
MinRating float64 `name:"min-rating" help:"Minimum average star rating (0-5)."`
Prime bool `help:"Only Prime-eligible offers."`
MinPrice float64 `name:"min-price" help:"Minimum price."`
MaxPrice float64 `name:"max-price" help:"Maximum price."`
Sort string `help:"Sort order (provider-defined, e.g. relevance, price-asc, rating)."`
Cursor string `help:"Opaque pagination cursor from a previous nextCursor."`
}
SearchCmd implements `rivr search <query>` (read).
type VariationsCmd ¶
type VariationsCmd struct {
ASIN string `arg:"" help:"Parent product ASIN."`
}
VariationsCmd implements `rivr variations <asin>` (read).
func (*VariationsCmd) Run ¶
func (c *VariationsCmd) Run(rt *Runtime) error
type VersionCmd ¶
type VersionCmd struct {
Check bool `help:"Check GitHub for a newer release (network)."`
}
func (*VersionCmd) Run ¶
func (c *VersionCmd) Run(rt *Runtime) error