eightstatecli 0.4.2__tar.gz → 0.4.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eightstatecli
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: Eightstate CLI — unified AI services from the command line
5
5
  Project-URL: Homepage, https://github.com/eight-state/eightstate
6
6
  Project-URL: Repository, https://github.com/eight-state/eightstate
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "eightstatecli"
3
- version = "0.4.2"
3
+ version = "0.4.3"
4
4
  description = "Eightstate CLI — unified AI services from the command line"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -17,7 +17,7 @@ AGENT INSTRUCTIONS:
17
17
  - Exit codes: 0=success, 1=error, 2=usage
18
18
  """
19
19
 
20
- __version__ = "0.4.1"
20
+ __version__ = "0.4.3"
21
21
 
22
22
  import argparse
23
23
  import base64
@@ -718,7 +718,7 @@ config: ~/.escli/config.json (600 permissions, owner-only)
718
718
  subs = root.add_subparsers(dest="command", metavar="command")
719
719
 
720
720
  # ── auth ──────────────────────────────────────────────────────────
721
- auth_p = subs.add_parser("auth", aliases=["a"], help="Authentication and profiles", formatter_class=F,
721
+ auth_p = subs.add_parser("auth", aliases=["a"], help="Manage API auth and profiles", formatter_class=F,
722
722
  epilog=f"""subcommands:
723
723
  login {DOT} authenticate with API key
724
724
  logout {DOT} remove credentials
@@ -733,7 +733,7 @@ agent examples:
733
733
  """)
734
734
  auth_subs = auth_p.add_subparsers(dest="auth_command", metavar="subcommand")
735
735
 
736
- login_p = auth_subs.add_parser("login", aliases=["l"], help="Authenticate with an API key", formatter_class=F,
736
+ login_p = auth_subs.add_parser("login", aliases=["l"], help="Authenticate via browser or API key", formatter_class=F,
737
737
  epilog=f"""examples:
738
738
  escli auth login {DOT} interactive prompt
739
739
  escli auth login --key sk-xxx {DOT} non-interactive (agents/CI)
@@ -745,24 +745,24 @@ agent: escli --json auth login --key sk-xxx
745
745
  """)
746
746
  login_p.add_argument("--key", "-k", default=None, help="API key (omit for interactive prompt)")
747
747
  login_p.add_argument("--profile", "-p", default="default", help="Profile name (default: default)")
748
- login_p.add_argument("--label", default=None, help="Human-readable label for this profile")
749
- login_p.add_argument("--endpoint", default=None, help=f"API endpoint (default: {ENDPOINT})")
748
+ login_p.add_argument("--label", default=None, help="Profile label")
749
+ login_p.add_argument("--endpoint", default=None, help="API endpoint")
750
750
  login_p.set_defaults(func=cmd_auth_login)
751
751
 
752
752
  logout_p = auth_subs.add_parser("logout", help="Remove stored credentials")
753
753
  logout_p.add_argument("--profile", "-p", default=None, help="Profile to remove (default: active)")
754
- logout_p.add_argument("--all", action="store_true", help="Remove ALL profiles")
754
+ logout_p.add_argument("--all", action="store_true", help="Remove all profiles")
755
755
  logout_p.set_defaults(func=cmd_auth_logout)
756
756
 
757
- auth_subs.add_parser("status", aliases=["s", "whoami"], help="Show current auth status").set_defaults(func=cmd_auth_status)
758
- auth_subs.add_parser("profiles", aliases=["ls", "list"], help="List all profiles").set_defaults(func=cmd_auth_profiles)
757
+ auth_subs.add_parser("status", aliases=["s", "whoami"], help="Show current profile and auth state").set_defaults(func=cmd_auth_status)
758
+ auth_subs.add_parser("profiles", aliases=["ls", "list"], help="List all stored profiles").set_defaults(func=cmd_auth_profiles)
759
759
 
760
- switch_p = auth_subs.add_parser("switch", aliases=["use"], help="Switch active profile")
760
+ switch_p = auth_subs.add_parser("switch", aliases=["use"], help="Switch the active profile")
761
761
  switch_p.add_argument("profile_name", help="Profile to activate")
762
762
  switch_p.set_defaults(func=cmd_auth_switch)
763
763
 
764
764
  # ── image ─────────────────────────────────────────────────────────
765
- image_p = subs.add_parser("image", aliases=["img", "i"], help="Image generation and editing", formatter_class=F,
765
+ image_p = subs.add_parser("image", aliases=["img", "i"], help="Generate or edit images from prompts", formatter_class=F,
766
766
  epilog=f"""subcommands:
767
767
  generate (gen, g) {DOT} generate image from text prompt
768
768
  edit (e) {DOT} edit existing image with instruction
@@ -777,29 +777,29 @@ sizes: square(1024x1024) landscape(1536x1024) portrait(1024x1536)
777
777
  image_subs = image_p.add_subparsers(dest="image_command", metavar="subcommand")
778
778
 
779
779
  def add_image_flags(p, include_input=False):
780
- p.add_argument("prompt", nargs="+", help="Text prompt describing desired image")
780
+ p.add_argument("prompt", nargs="+", help="Text prompt")
781
781
  p.add_argument("-s", "--size", default=os.environ.get("ESCLI_IMAGE_SIZE", DEFAULTS["size"]),
782
- help="Image size: square|sq|landscape|wide|ls|portrait|tall|port or WxH (default: square = 1024x1024)")
782
+ help="Size: sq|wide|tall or WxH (default: 1024x1024)")
783
783
  p.add_argument("-q", "--quality", default=os.environ.get("ESCLI_IMAGE_QUALITY", DEFAULTS["quality"]),
784
- choices=VALID_QUALITIES, help="Quality: low (fast, ~15s) | medium (~25s) | high (best, ~40s) (default: high)")
784
+ choices=VALID_QUALITIES, help="Quality: low|medium|high (default: high)")
785
785
  p.add_argument("-f", "--format", default=os.environ.get("ESCLI_IMAGE_FORMAT", DEFAULTS["format"]),
786
- choices=VALID_FORMATS, help="Output format: png | jpeg | jpg | webp (default: png)")
786
+ choices=VALID_FORMATS, help="Format: png|jpeg|webp (default: png)")
787
787
  p.add_argument("-m", "--model", default=os.environ.get("ESCLI_IMAGE_MODEL", DEFAULTS["model"]),
788
- help="Model to use (default: gpt-image-2)")
788
+ help="Model (default: gpt-image-2)")
789
789
  p.add_argument("-o", "--output", default=None,
790
- help="Output file path. If omitted, auto-generates: YYYYMMDD-HHMMSS-slugified-prompt.png")
790
+ help="Output path (default: auto-named in --out-dir)")
791
791
  p.add_argument("-d", "--out-dir", default=os.environ.get("ESCLI_OUT_DIR", DEFAULTS["out_dir"]),
792
- help="Output directory when -o not set (default: current dir)")
793
- p.add_argument("--open", action="store_true", help="Open image in default viewer after generating")
792
+ help="Output dir (default: .)")
793
+ p.add_argument("--open", action="store_true", help="Open result after writing")
794
794
  p.add_argument("--compression", type=int, default=None, metavar="0-100",
795
- help="Output compression level for jpeg/webp (0=min, 100=max)")
795
+ help="JPEG/WebP compression 0-100")
796
796
  p.add_argument("--moderation", default=None, choices=["auto", "low"],
797
- help="Content moderation: auto (default) | low (permissive)")
797
+ help="Moderation: auto|low")
798
798
  if include_input:
799
799
  p.add_argument("-i", "--input", required=True,
800
- help="Path to input image file to edit (png, jpg, webp)")
800
+ help="Input image (png/jpg/webp)")
801
801
  p.add_argument("--fidelity", default=None, choices=["low", "high"],
802
- help="How closely to preserve the input image: low (more creative) | high (more faithful)")
802
+ help="Fidelity to input: low|high")
803
803
 
804
804
  gen_p = image_subs.add_parser("generate", aliases=["gen", "g"], help="Generate an image from a text prompt",
805
805
  formatter_class=F, epilog=f"""sizes (any of these work for -s):
@@ -834,7 +834,7 @@ agent examples:
834
834
  """)
835
835
  add_image_flags(gen_p)
836
836
  gen_p.add_argument("--background", default=None, choices=VALID_BACKGROUNDS,
837
- help="Background: auto (default) | transparent (removes background)")
837
+ help="Background: auto|transparent")
838
838
  gen_p.set_defaults(func=cmd_image_generate)
839
839
 
840
840
  edit_p = image_subs.add_parser("edit", aliases=["e"], help="Edit an existing image with an instruction",
@@ -863,7 +863,7 @@ supported input formats: png, jpg, jpeg, webp
863
863
  edit_p.set_defaults(func=cmd_image_edit)
864
864
 
865
865
  # ── models ────────────────────────────────────────────────────────
866
- subs.add_parser("models", aliases=["m"], help="List available models", formatter_class=F,
866
+ subs.add_parser("models", aliases=["m"], help="List models available on the endpoint", formatter_class=F,
867
867
  epilog=f"""lists all models available on the API endpoint.
868
868
 
869
869
  agent example:
@@ -896,7 +896,7 @@ agent example:
896
896
  register_usage(subs)
897
897
 
898
898
  # ── version ───────────────────────────────────────────────────────
899
- subs.add_parser("version", help="Show version info").set_defaults(func=cmd_version)
899
+ subs.add_parser("version", help="Print escli version").set_defaults(func=cmd_version)
900
900
 
901
901
  return root
902
902
 
@@ -394,7 +394,7 @@ def register(subparsers):
394
394
  F = argparse.RawDescriptionHelpFormatter
395
395
 
396
396
  audio_p = subparsers.add_parser(
397
- "audio", aliases=["au"], help="Audio transcription (AssemblyAI)",
397
+ "audio", aliases=["au"], help="Transcribe audio files or URLs",
398
398
  formatter_class=F,
399
399
  epilog="""subcommands:
400
400
  transcribe <file-or-url> Transcribe audio with speaker diarization
@@ -413,42 +413,42 @@ examples:
413
413
  audio_subs = audio_p.add_subparsers(dest="audio_command", metavar="subcommand")
414
414
 
415
415
  # transcribe
416
- tr_p = audio_subs.add_parser("transcribe", aliases=["t"], help="Transcribe audio")
416
+ tr_p = audio_subs.add_parser("transcribe", aliases=["t"], help="Transcribe an audio file or URL")
417
417
  tr_p.add_argument("source", help="Audio file path or URL")
418
- tr_p.add_argument("-o", "--output", default=None, help="Write output to file")
419
- tr_p.add_argument("--format", choices=["text", "json", "srt", "vtt"], default="text", help="Output format")
418
+ tr_p.add_argument("-o", "--output", default=None, help="Output file")
419
+ tr_p.add_argument("--format", choices=["text", "json", "srt", "vtt"], default="text", help="Output format: text|json|srt|vtt")
420
420
  # Speaker diarization
421
- tr_p.add_argument("--speakers", action="store_true", help="Enable speaker labels")
421
+ tr_p.add_argument("--speakers", action="store_true", help="Speaker diarization")
422
422
  tr_p.add_argument("--speakers-expected", type=int, default=None, metavar="N", help="Expected speaker count (1-20)")
423
- tr_p.add_argument("--speaker-names", default=None, metavar="A,B,C", help="Identify speakers by name")
423
+ tr_p.add_argument("--speaker-names", default=None, metavar="A,B,C", help="Identify speakers by name (comma-separated)")
424
424
  # Audio intelligence
425
- tr_p.add_argument("--sentiment", action="store_true", help="Enable sentiment analysis")
426
- tr_p.add_argument("--chapters", action="store_true", help="Enable auto chapters")
427
- tr_p.add_argument("--entities", action="store_true", help="Enable entity detection")
428
- tr_p.add_argument("--summarize", action="store_true", help="Enable summarization")
429
- tr_p.add_argument("--highlights", action="store_true", help="Enable auto highlights")
430
- tr_p.add_argument("--topics", action="store_true", help="Enable topic detection (IAB)")
431
- tr_p.add_argument("--content-safety", action="store_true", help="Enable content safety detection")
425
+ tr_p.add_argument("--sentiment", action="store_true", help="Sentiment analysis")
426
+ tr_p.add_argument("--chapters", action="store_true", help="Auto chapters")
427
+ tr_p.add_argument("--entities", action="store_true", help="Entity detection")
428
+ tr_p.add_argument("--summarize", action="store_true", help="Summarization")
429
+ tr_p.add_argument("--highlights", action="store_true", help="Auto highlights")
430
+ tr_p.add_argument("--topics", action="store_true", help="IAB topic detection")
431
+ tr_p.add_argument("--content-safety", action="store_true", help="Content safety detection")
432
432
  # Transcription options
433
433
  tr_p.add_argument("--language", default=None, metavar="CODE", help="Language code (default: auto-detect)")
434
434
  tr_p.add_argument("--dual-channel", action="store_true", help="Dual channel transcription")
435
435
  tr_p.add_argument("--multichannel", action="store_true", help="Multichannel transcription")
436
- tr_p.add_argument("--word-boost", default=None, metavar="W1,W2", help="Boost accuracy for words")
436
+ tr_p.add_argument("--word-boost", default=None, metavar="W1,W2", help="Boost accuracy for words (comma-separated)")
437
437
  tr_p.add_argument("--disfluencies", action="store_true", help="Include filler words")
438
438
  tr_p.add_argument("--filter-profanity", action="store_true", help="Filter profanity")
439
439
  tr_p.add_argument("--redact-pii", action="store_true", help="Redact PII")
440
440
  tr_p.set_defaults(func=cmd_transcribe)
441
441
 
442
442
  # status
443
- st_p = audio_subs.add_parser("status", aliases=["s"], help="Check transcript status")
443
+ st_p = audio_subs.add_parser("status", aliases=["s"], help="Check transcript job status")
444
444
  st_p.add_argument("transcript_id", help="Transcript ID")
445
445
  st_p.set_defaults(func=cmd_status)
446
446
 
447
447
  # get
448
- get_p = audio_subs.add_parser("get", aliases=["g"], help="Fetch completed transcript")
448
+ get_p = audio_subs.add_parser("get", aliases=["g"], help="Fetch a completed transcript")
449
449
  get_p.add_argument("transcript_id", help="Transcript ID")
450
- get_p.add_argument("--format", choices=["text", "json", "srt", "vtt"], default="text", help="Output format")
451
- get_p.add_argument("-o", "--output", default=None, help="Write output to file")
450
+ get_p.add_argument("--format", choices=["text", "json", "srt", "vtt"], default="text", help="Output format: text|json|srt|vtt")
451
+ get_p.add_argument("-o", "--output", default=None, help="Output file")
452
452
  get_p.set_defaults(func=cmd_get)
453
453
 
454
454
  # list
@@ -333,7 +333,7 @@ def register(subparsers):
333
333
  F = argparse.RawDescriptionHelpFormatter
334
334
 
335
335
  docs_p = subparsers.add_parser(
336
- "docs", aliases=["d"], help="Library documentation search (Context7)",
336
+ "docs", aliases=["d"], help="Fetch up-to-date library docs",
337
337
  formatter_class=F,
338
338
  epilog="""subcommands:
339
339
  search <library> Search for libraries
@@ -350,30 +350,30 @@ examples:
350
350
  docs_subs = docs_p.add_subparsers(dest="docs_command", metavar="subcommand")
351
351
 
352
352
  # search
353
- search_p = docs_subs.add_parser("search", aliases=["s"], help="Search for libraries")
354
- search_p.add_argument("library_name", help="Library name to search for")
353
+ search_p = docs_subs.add_parser("search", aliases=["s"], help="Search for libraries by name")
354
+ search_p.add_argument("library_name", help="Library name")
355
355
  search_p.add_argument("query", nargs="?", default=None, help="Optional search query")
356
- search_p.add_argument("--limit", type=int, default=10, help="Limit results (default: 10)")
356
+ search_p.add_argument("--limit", type=int, default=10, help="Max results (default: 10)")
357
357
  search_p.add_argument("--refresh", action="store_true", help="Bypass cache")
358
358
  search_p.set_defaults(func=cmd_search)
359
359
 
360
360
  # get (one-shot: resolve + fetch)
361
- get_p = docs_subs.add_parser("get", aliases=["g"], help="Resolve + fetch docs")
361
+ get_p = docs_subs.add_parser("get", aliases=["g"], help="Resolve a library and fetch docs in one shot")
362
362
  get_p.add_argument("library_name", help="Library name")
363
363
  get_p.add_argument("query", help="Documentation query")
364
364
  get_p.add_argument("--tokens", type=int, default=None, help="Max tokens to return")
365
365
  get_p.add_argument("--page", type=int, default=None, help="Page number (1-10)")
366
- get_p.add_argument("--topic", default=None, help="Focus on specific topic")
366
+ get_p.add_argument("--topic", default=None, help="Focus on a topic")
367
367
  get_p.add_argument("--refresh", action="store_true", help="Bypass cache")
368
368
  get_p.set_defaults(func=cmd_get)
369
369
 
370
370
  # fetch (by library ID)
371
- fetch_p = docs_subs.add_parser("fetch", aliases=["f"], help="Fetch docs by library ID")
371
+ fetch_p = docs_subs.add_parser("fetch", aliases=["f"], help="Fetch docs by exact library ID")
372
372
  fetch_p.add_argument("library_id", help="Library ID (e.g. /facebook/react)")
373
373
  fetch_p.add_argument("query", help="Documentation query")
374
374
  fetch_p.add_argument("--tokens", type=int, default=None, help="Max tokens to return")
375
375
  fetch_p.add_argument("--page", type=int, default=None, help="Page number (1-10)")
376
- fetch_p.add_argument("--topic", default=None, help="Focus on specific topic")
376
+ fetch_p.add_argument("--topic", default=None, help="Focus on a topic")
377
377
  fetch_p.add_argument("--refresh", action="store_true", help="Bypass cache")
378
378
  fetch_p.set_defaults(func=cmd_fetch)
379
379
 
@@ -700,7 +700,7 @@ def register(subparsers):
700
700
  F = argparse.RawDescriptionHelpFormatter
701
701
 
702
702
  p = subparsers.add_parser(
703
- "research", aliases=["r"], help="Web research tasks (Parallel Task API)",
703
+ "research", aliases=["r"], help="Run deep web research tasks",
704
704
  formatter_class=F,
705
705
  epilog="""modes:
706
706
  escli research "query" -o report.md Run a research task (default)
@@ -737,31 +737,31 @@ output modes:
737
737
  mode_g.add_argument("--result", default=None, metavar="RUN_ID", help="Fetch completed task result")
738
738
 
739
739
  # Run options
740
- p.add_argument("-o", "--output", default=None, help="Output file path (markdown or JSON)")
740
+ p.add_argument("-o", "--output", default=None, help="Output path (md or json)")
741
741
  p.add_argument("-p", "--processor", default="pro", choices=PROCESSORS, help="Processor tier (default: pro)")
742
742
 
743
743
  # Output schema
744
744
  schema_g = p.add_argument_group("output schema")
745
- schema_g.add_argument("--text", action="store_true", help="Markdown report format")
745
+ schema_g.add_argument("--text", action="store_true", help="Markdown report output")
746
746
  schema_g.add_argument("--schema", default=None, metavar="FILE", help="JSON Schema file for structured output")
747
- schema_g.add_argument("--output-schema", default=None, metavar="STR", help="Inline output schema description")
747
+ schema_g.add_argument("--output-schema", default=None, metavar="STR", help="Inline schema description")
748
748
 
749
749
  # Input
750
750
  input_g = p.add_argument_group("input")
751
- input_g.add_argument("--input-json", default=None, metavar="JSON", help="JSON object as input (instead of text)")
752
- input_g.add_argument("--input-file", default=None, metavar="FILE", help="JSON file as input")
751
+ input_g.add_argument("--input-json", default=None, metavar="JSON", help="JSON input (instead of text)")
752
+ input_g.add_argument("--input-file", default=None, metavar="FILE", help="JSON input file")
753
753
 
754
754
  # Source policy
755
755
  source_g = p.add_argument_group("source policy")
756
756
  source_g.add_argument("--include-domains", default=None, metavar="D1,D2", help="Only use these domains")
757
757
  source_g.add_argument("--exclude-domains", default=None, metavar="D1,D2", help="Exclude these domains")
758
- source_g.add_argument("--after-date", default=None, metavar="YYYY-MM-DD", help="Only content after this date")
758
+ source_g.add_argument("--after-date", default=None, metavar="YYYY-MM-DD", help="Filter content after this date")
759
759
 
760
760
  # Advanced
761
761
  adv_g = p.add_argument_group("advanced")
762
- adv_g.add_argument("--location", default=None, metavar="CC", help="ISO country code for geo-targeted results")
762
+ adv_g.add_argument("--location", default=None, metavar="CC", help="ISO country code for geo-targeting")
763
763
  adv_g.add_argument("--metadata", default=None, help="Metadata as JSON or key=val,key=val")
764
- adv_g.add_argument("--follow-up", default=None, metavar="RUN_ID", help="Follow-up on a previous task run")
764
+ adv_g.add_argument("--follow-up", default=None, metavar="RUN_ID", help="Follow up on a previous run")
765
765
  adv_g.add_argument("--no-basis", action="store_true", help="Exclude citations and reasoning")
766
766
 
767
767
  p.set_defaults(func=_dispatch)
@@ -268,7 +268,7 @@ def register(subparsers):
268
268
 
269
269
  # search
270
270
  search_p = subparsers.add_parser(
271
- "search", aliases=["s"], help="Web search (Parallel.ai)",
271
+ "search", aliases=["s"], help="Search the web, return ranked excerpts",
272
272
  formatter_class=F,
273
273
  epilog="""examples:
274
274
  escli search "latest cloudflare workers features"
@@ -278,14 +278,14 @@ def register(subparsers):
278
278
  Uses the free Parallel Search MCP. No API key needed.
279
279
  Add a Parallel API key for higher rate limits.
280
280
  """)
281
- search_p.add_argument("objective", nargs="+", help="What you're searching for")
281
+ search_p.add_argument("objective", nargs="+", help="Search objective")
282
282
  search_p.add_argument("--queries", nargs="+", default=None, metavar="Q",
283
- help="Specific search queries (default: uses objective)")
283
+ help="Override queries (default: objective)")
284
284
  search_p.set_defaults(func=cmd_search)
285
285
 
286
286
  # fetch
287
287
  fetch_p = subparsers.add_parser(
288
- "fetch", aliases=["f"], help="Extract URL content (Parallel.ai)",
288
+ "fetch", aliases=["f"], help="Extract clean content from URLs",
289
289
  formatter_class=F,
290
290
  epilog="""examples:
291
291
  escli fetch https://docs.parallel.ai/search/search-quickstart
@@ -295,9 +295,9 @@ Add a Parallel API key for higher rate limits.
295
295
 
296
296
  Uses the free Parallel Extract MCP. No API key needed.
297
297
  """)
298
- fetch_p.add_argument("urls", nargs="+", help="URLs to extract content from")
299
- fetch_p.add_argument("--objective", default=None, help="Focus extraction on this topic")
300
- fetch_p.add_argument("--full", action="store_true", help="Return full page content instead of excerpts")
298
+ fetch_p.add_argument("urls", nargs="+", help="URLs to extract")
299
+ fetch_p.add_argument("--objective", default=None, help="Focus on this topic")
300
+ fetch_p.add_argument("--full", action="store_true", help="Return full content (not excerpts)")
301
301
  fetch_p.set_defaults(func=cmd_fetch)
302
302
 
303
303
  return search_p
@@ -215,7 +215,7 @@ def register(subparsers):
215
215
  F = argparse.RawDescriptionHelpFormatter
216
216
 
217
217
  p = subparsers.add_parser(
218
- "social", help="Social media search (Tavily)",
218
+ "social", help="Search posts across social platforms",
219
219
  formatter_class=F,
220
220
  epilog="""platforms:
221
221
  reddit, x, tiktok, linkedin, instagram, facebook, youtube, combined (default)
@@ -235,11 +235,11 @@ time ranges:
235
235
  year Last 12 months
236
236
  """)
237
237
 
238
- p.add_argument("query", nargs="+", help="What to search for on social media")
238
+ p.add_argument("query", nargs="+", help="Search query")
239
239
  p.add_argument("--platform", "-p", default=None, metavar="P",
240
- help=f"Platform(s) to search, comma-separated ({', '.join(VALID_PLATFORMS)})")
240
+ help=f"Platform(s), comma-separated ({', '.join(VALID_PLATFORMS)})")
241
241
  p.add_argument("--time", "-t", default=None, choices=VALID_TIME_RANGES, metavar="T",
242
- help="Time range: day, week, month, year")
242
+ help="Time range: day|week|month|year")
243
243
  p.add_argument("--max-results", "-n", type=int, default=10, metavar="N",
244
244
  help="Max results (1-20, default: 10)")
245
245
  p.add_argument("--depth", default="advanced", choices=VALID_DEPTHS,
@@ -247,11 +247,11 @@ time ranges:
247
247
  p.add_argument("--answer", "-a", action="store_true",
248
248
  help="Include AI-synthesized answer")
249
249
  p.add_argument("--raw", action="store_true",
250
- help="Include full post content (raw markdown)")
250
+ help="Include full post content")
251
251
  p.add_argument("--images", action="store_true",
252
- help="Include images from results")
252
+ help="Include images")
253
253
  p.add_argument("--country", default=None, metavar="CC",
254
- help="Country for geo-targeted results (e.g. 'united states')")
254
+ help="Country for geo-targeting (e.g. 'united states')")
255
255
  p.set_defaults(func=cmd_social)
256
256
 
257
257
  return p
@@ -390,7 +390,7 @@ def register(subparsers):
390
390
  F = argparse.RawDescriptionHelpFormatter
391
391
 
392
392
  p = subparsers.add_parser(
393
- "usage", aliases=["u"], help="API usage and spend analytics",
393
+ "usage", aliases=["u"], help="Show API usage and spend",
394
394
  formatter_class=F,
395
395
  epilog=f"""examples:
396
396
  escli usage {DOT} summary, last 30 days
@@ -418,11 +418,11 @@ auth: requires `escli auth login` (uses CLI token, not API key).
418
418
  p.add_argument("--days", type=int, default=30, metavar="N",
419
419
  help="Window size in days (default: 30)")
420
420
  p.add_argument("--service", default=None, metavar="NAME",
421
- help="Filter to a single service (e.g. parallel, openai, assemblyai)")
421
+ help="Filter to one service (parallel|openai|assemblyai|...)")
422
422
  p.add_argument("--daily", action="store_true",
423
- help="Show day-by-day breakdown")
423
+ help="Day-by-day breakdown")
424
424
  p.add_argument("--pricing", action="store_true",
425
- help="Show current pricing rules (ignores --days/--service)")
425
+ help="Show current pricing rules")
426
426
  p.set_defaults(func=cmd_usage)
427
427
 
428
428
  return p
File without changes
File without changes
File without changes