From 90dfcd8b09a73de620ed1492fd270e53285c7eb2 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 22 Sep 2026 23:28:42 +0000 Subject: [PATCH 1/2] UX: Standardize CLI help text for JSON output flags Co-authored-by: tteon <52625664+tteon@users.noreply.github.com> --- .jules/palette.md | 3 +++ src/seocho/cli/ontology.py | 46 +++++++++++++++++++------------------- src/seocho/cli/options.py | 2 +- src/seocho/cli/parsers.py | 18 +++++++-------- src/seocho/cli/runs.py | 2 +- 5 files changed, 37 insertions(+), 34 deletions(-) create mode 100644 .jules/palette.md diff --git a/.jules/palette.md b/.jules/palette.md new file mode 100644 index 00000000..ca5fdd19 --- /dev/null +++ b/.jules/palette.md @@ -0,0 +1,3 @@ +- CLI help strings for --json parameters are inconsistent ("Emit JSON output", "JSON output", "Emit JSON", missing help text). +- Based on repo rules: In the SEOCHO repository's CLI (`src/seocho/cli/`), the standard help string for JSON output arguments (`--json`) is `help="Emit JSON"`. +- Will standardize this as a clear UX/a11y improvement for CLI help text. diff --git a/src/seocho/cli/ontology.py b/src/seocho/cli/ontology.py index 240d4058..2cd929eb 100644 --- a/src/seocho/cli/ontology.py +++ b/src/seocho/cli/ontology.py @@ -21,7 +21,7 @@ def register(subparsers) -> None: ontology_check_parser = ontology_subparsers.add_parser("check", help="Validate one ontology definition") ontology_check_parser.add_argument("--schema", required=True, help="Ontology file (JSON-LD, YAML, or TTL)") - ontology_check_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_check_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_export_parser = ontology_subparsers.add_parser("export", help="Export ontology-derived artifacts") ontology_export_parser.add_argument("--schema", required=True, help="Ontology file (JSON-LD, YAML, or TTL)") @@ -32,12 +32,12 @@ def register(subparsers) -> None: help="Output artifact format", ) ontology_export_parser.add_argument("--output", default=None, help="Optional output file path") - ontology_export_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_export_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_diff_parser = ontology_subparsers.add_parser("diff", help="Diff two ontology definitions") ontology_diff_parser.add_argument("--left", required=True, help="Left ontology file") ontology_diff_parser.add_argument("--right", required=True, help="Right ontology file") - ontology_diff_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_diff_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_report_parser = ontology_subparsers.add_parser( "report", @@ -51,14 +51,14 @@ def register(subparsers) -> None: action="store_true", help="Skip optional Owlready2 offline inspection", ) - ontology_report_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_report_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_inspect_parser = ontology_subparsers.add_parser( "inspect-owl", help="Inspect an OWL ontology with Owlready2 (optional offline dependency)", ) ontology_inspect_parser.add_argument("--source", required=True, help="OWL file path or URI") - ontology_inspect_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_inspect_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_rdf_governance_parser = ontology_subparsers.add_parser( "rdf-governance", help="Run hash-pinned offline SHACL and optional OWL consistency checks", @@ -68,7 +68,7 @@ def register(subparsers) -> None: ontology_rdf_governance_parser.add_argument("--data-format", default="turtle", help="RDF data format for pySHACL") ontology_rdf_governance_parser.add_argument("--run-reasoner", action="store_true", help="Run optional offline Owlready2/Pellet consistency check") ontology_rdf_governance_parser.add_argument("--output", default=None, help="Optional receipt JSON path") - ontology_rdf_governance_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_rdf_governance_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_review_parser = ontology_subparsers.add_parser( "review", @@ -88,7 +88,7 @@ def register(subparsers) -> None: ontology_review_parser.add_argument("--spec", default=None, help="Mapping-spec YAML (for apply)") ontology_review_parser.add_argument("--output", default=None, help="Output path (export-spec / apply)") ontology_review_parser.add_argument("--workspace", default="", help="workspace_id to stamp on quarantined items") - ontology_review_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_review_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_datahub_parser = ontology_subparsers.add_parser( "datahub", @@ -99,7 +99,7 @@ def register(subparsers) -> None: ontology_datahub_parser.add_argument("--gms", default=None, help="DataHub GMS server URL (for live emit)") ontology_datahub_parser.add_argument("--token", default=None, help="DataHub access token (for live emit)") ontology_datahub_parser.add_argument("--emit", action="store_true", help="Actually emit to --gms (default: dry-run)") - ontology_datahub_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_datahub_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_select_parser = ontology_subparsers.add_parser( "select-guardrail", @@ -113,7 +113,7 @@ def register(subparsers) -> None: "--corpus", required=True, help="Corpus profile JSON (label->freq, a CorpusProfile dict, or an experiment record)", ) - ontology_select_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_select_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_dhapply_parser = ontology_subparsers.add_parser( "datahub-apply", @@ -128,7 +128,7 @@ def register(subparsers) -> None: help="DataHub GMS URL to pull reviewed glossary terms from live (instead of --terms)") ontology_dhapply_parser.add_argument("--status", default="APPROVED", help="Only apply terms with this review status") ontology_dhapply_parser.add_argument("--output", default=None, help="Write the new ontology JSON-LD here") - ontology_dhapply_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_dhapply_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_dhqueue_parser = ontology_subparsers.add_parser( "datahub-queue", @@ -140,7 +140,7 @@ def register(subparsers) -> None: ontology_dhqueue_parser.add_argument("--token", default=None, help="DataHub access token (for live emit)") ontology_dhqueue_parser.add_argument("--emit", action="store_true", help="Actually emit to --gms (default: dry-run)") ontology_dhqueue_parser.add_argument("--output", default=None, help="Write MCP JSON to this path (dry-run)") - ontology_dhqueue_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_dhqueue_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_eval_answers_parser = ontology_subparsers.add_parser( "eval-answers", @@ -154,7 +154,7 @@ def register(subparsers) -> None: ontology_eval_answers_parser.add_argument("--provider", default="mara", help="LLM provider preset (default: mara)") ontology_eval_answers_parser.add_argument("--model", default=None, help="Model override (default: provider default)") ontology_eval_answers_parser.add_argument("--workers", type=int, default=6, help="Concurrent workers (default: 6)") - ontology_eval_answers_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_eval_answers_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_learn_parser = ontology_subparsers.add_parser( "learn", help="Create a review-only LLMs4OL candidate report from an extracted graph", @@ -163,7 +163,7 @@ def register(subparsers) -> None: ontology_learn_parser.add_argument("--graph", required=True, help="Extracted graph JSON input") ontology_learn_parser.add_argument("--output", required=True, help="Explicit review-report JSON output path") ontology_learn_parser.add_argument("--min-support", type=int, default=2, help="Minimum observed support per candidate") - ontology_learn_parser.add_argument("--json", dest="output_json", action="store_true", help="JSON output") + ontology_learn_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") ontology_import_parser = ontology_subparsers.add_parser( @@ -179,7 +179,7 @@ def register(subparsers) -> None: "--output", default=None, help="Write the draft document here (YAML); default prints to stdout") ontology_import_parser.add_argument( - "--json", dest="output_json", action="store_true", help="JSON output") + "--json", dest="output_json", action="store_true", help="Emit JSON") ontology_subparsers.add_parser( @@ -192,7 +192,7 @@ def register(subparsers) -> None: ontology_clone_parser.add_argument("template", help="Template name (see `ontology templates`)") ontology_clone_parser.add_argument("--output", default=None, help="Write the draft YAML here") ontology_clone_parser.add_argument( - "--json", dest="output_json", action="store_true", help="JSON output") + "--json", dest="output_json", action="store_true", help="Emit JSON") # Lifecycle commands deliberately use explicit state/root arguments. They # never infer a host path from an agent prompt or a bundle manifest. @@ -201,16 +201,16 @@ def register(subparsers) -> None: bundle_build = bundle_sub.add_parser("build", help="Atomically publish a new immutable bundle") bundle_build.add_argument("--schema", required=True) bundle_build.add_argument("--output", required=True, help="New (nonexistent) bundle directory") - bundle_build.add_argument("--json", dest="output_json", action="store_true") + bundle_build.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") bundle_verify = bundle_sub.add_parser("verify", help="Verify manifest and artifact hashes") bundle_verify.add_argument("--bundle", required=True) - bundle_verify.add_argument("--json", dest="output_json", action="store_true") + bundle_verify.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") def lifecycle_args(parser: argparse.ArgumentParser) -> None: parser.add_argument("--state-db", default=".seocho/ontology/state.sqlite", help="Single-host SQLite/WAL state database") parser.add_argument("--workspace", required=True) parser.add_argument("--package", required=True) - parser.add_argument("--json", dest="output_json", action="store_true") + parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") activate = ontology_subparsers.add_parser("activate", help="CAS-activate a verified immutable bundle") lifecycle_args(activate) @@ -227,7 +227,7 @@ def lifecycle_args(parser: argparse.ArgumentParser) -> None: lp = lease_sub.add_parser(action) lp.add_argument("--state-db", default=".seocho/ontology/state.sqlite") lp.add_argument("--owner", required=True, help="Stable process identity, never a model-generated value") - lp.add_argument("--json", dest="output_json", action="store_true") + lp.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") if action == "acquire": lp.add_argument("--workspace", required=True); lp.add_argument("--package", required=True) lp.add_argument("--purpose", required=True); lp.add_argument("--ttl", type=int, default=60) @@ -242,7 +242,7 @@ def lifecycle_args(parser: argparse.ArgumentParser) -> None: for action in ("acquire", "renew", "release"): lp = lock_sub.add_parser(action) lp.add_argument("--state-db", default=".seocho/ontology/state.sqlite") - lp.add_argument("--owner", required=True); lp.add_argument("--json", dest="output_json", action="store_true") + lp.add_argument("--owner", required=True); lp.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") if action == "acquire": lp.add_argument("--workspace", required=True); lp.add_argument("--package", required=True) lp.add_argument("--purpose", required=True); lp.add_argument("--ttl", type=int, default=60) @@ -253,18 +253,18 @@ def lifecycle_args(parser: argparse.ArgumentParser) -> None: gc = ontology_subparsers.add_parser("gc", help="Report candidate immutable bundles; dry-run only") gc.add_argument("--root", required=True, help="Directory containing immutable bundle directories") gc.add_argument("--dry-run", action="store_true", required=True, help="Required: no deletion is implemented") - gc.add_argument("--json", dest="output_json", action="store_true") + gc.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") context_parser = ontology_subparsers.add_parser("context", help="Return verified, bounded ontology context for an agent") context_sub = context_parser.add_subparsers(dest="context_action", required=True) profile_parser = context_sub.add_parser("profile", help="Return one purpose-scoped immutable profile") profile_parser.add_argument("--bundle", required=True); profile_parser.add_argument("--purpose", required=True, choices=["indexing", "query", "projection"]) - profile_parser.add_argument("--json", dest="output_json", action="store_true") + profile_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") slice_parser = context_sub.add_parser("slice", help="Return a bounded JIT slice; never raw ontology files") slice_parser.add_argument("--bundle", required=True); slice_parser.add_argument("--purpose", required=True, choices=["indexing", "query", "projection"]) slice_parser.add_argument("--terms", required=True, help="Comma-separated retrieval terms") slice_parser.add_argument("--max-chars", type=int, default=4000) - slice_parser.add_argument("--json", dest="output_json", action="store_true") + slice_parser.add_argument("--json", dest="output_json", action="store_true", help="Emit JSON") def handle(args: argparse.Namespace) -> int: diff --git a/src/seocho/cli/options.py b/src/seocho/cli/options.py index 9b1ebe68..0da5a292 100644 --- a/src/seocho/cli/options.py +++ b/src/seocho/cli/options.py @@ -23,5 +23,5 @@ def add_client_options( parser.add_argument("--session-id", default=None, help="Session scope") if include_json: parser.add_argument( - "--json", dest="output_json", action="store_true", help="Emit JSON output" + "--json", dest="output_json", action="store_true", help="Emit JSON" ) diff --git a/src/seocho/cli/parsers.py b/src/seocho/cli/parsers.py index ece38148..cb074bde 100644 --- a/src/seocho/cli/parsers.py +++ b/src/seocho/cli/parsers.py @@ -171,7 +171,7 @@ def register_memory_commands(subparsers: Any) -> None: help="Print the compose command without running it", ) serve_parser.add_argument( - "--json", dest="output_json", action="store_true", help="Emit JSON output" + "--json", dest="output_json", action="store_true", help="Emit JSON" ) stop_parser = subparsers.add_parser( @@ -194,7 +194,7 @@ def register_memory_commands(subparsers: Any) -> None: help="Print the compose command without running it", ) stop_parser.add_argument( - "--json", dest="output_json", action="store_true", help="Emit JSON output" + "--json", dest="output_json", action="store_true", help="Emit JSON" ) artifacts_parser = subparsers.add_parser( @@ -376,7 +376,7 @@ def register_local_commands(subparsers: Any) -> None: "--strict", action="store_true", help="Reject data that fails SHACL validation" ) index_parser.add_argument( - "--json", dest="output_json", action="store_true", help="JSON output" + "--json", dest="output_json", action="store_true", help="Emit JSON" ) local_ask_parser = subparsers.add_parser( @@ -413,7 +413,7 @@ def register_local_commands(subparsers: Any) -> None: "--repair-budget", type=int, default=2, help="Max repair attempts" ) local_ask_parser.add_argument( - "--json", dest="output_json", action="store_true", help="JSON output" + "--json", dest="output_json", action="store_true", help="Emit JSON" ) status_parser = subparsers.add_parser("status", help="Show graph database status") @@ -443,7 +443,7 @@ def register_local_commands(subparsers: Any) -> None: "--llm-base-url", default=None, help="Override the provider base URL" ) status_parser.add_argument( - "--json", dest="output_json", action="store_true", help="JSON output" + "--json", dest="output_json", action="store_true", help="Emit JSON" ) compare_parser = subparsers.add_parser( @@ -465,7 +465,7 @@ def register_local_commands(subparsers: Any) -> None: "--model-b", default=None, help="LLM model for config B (default: same as A)" ) compare_parser.add_argument( - "--json", dest="output_json", action="store_true", help="JSON output" + "--json", dest="output_json", action="store_true", help="Emit JSON" ) experiment_parser = subparsers.add_parser( @@ -504,7 +504,7 @@ def register_local_commands(subparsers: Any) -> None: "--output", default=None, help="Save results to this directory" ) experiment_parser.add_argument( - "--json", dest="output_json", action="store_true", help="JSON output" + "--json", dest="output_json", action="store_true", help="Emit JSON" ) bundle_parser = subparsers.add_parser( @@ -565,7 +565,7 @@ def register_local_commands(subparsers: Any) -> None: help="Optional extraction prompt preset to serialize into the portable bundle", ) bundle_export_parser.add_argument( - "--json", dest="output_json", action="store_true", help="JSON output" + "--json", dest="output_json", action="store_true", help="Emit JSON" ) bundle_show_parser = bundle_subparsers.add_parser( @@ -573,7 +573,7 @@ def register_local_commands(subparsers: Any) -> None: ) bundle_show_parser.add_argument("bundle", help="Path to bundle JSON file") bundle_show_parser.add_argument( - "--json", dest="output_json", action="store_true", help="JSON output" + "--json", dest="output_json", action="store_true", help="Emit JSON" ) serve_http_parser = subparsers.add_parser( diff --git a/src/seocho/cli/runs.py b/src/seocho/cli/runs.py index ccdc1d28..70b0acc7 100644 --- a/src/seocho/cli/runs.py +++ b/src/seocho/cli/runs.py @@ -28,7 +28,7 @@ def register(subparsers: Any) -> None: compare.add_argument( "--output-dir", type=Path, help="Write comparison.json/md to a new directory" ) - compare.add_argument("--json", action="store_true", dest="output_json") + compare.add_argument("--json", action="store_true", dest="output_json", help="Emit JSON") view = commands.add_parser( "view", help="Export a local interactive HTML view of saved results" From 268ef8d8875a2fb20c7dfa05223653d116a5004f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 22 Sep 2026 23:33:53 +0000 Subject: [PATCH 2/2] UX: Standardize CLI help text for JSON output flags Co-authored-by: tteon <52625664+tteon@users.noreply.github.com> --- .jules/palette.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .jules/palette.md diff --git a/.jules/palette.md b/.jules/palette.md deleted file mode 100644 index ca5fdd19..00000000 --- a/.jules/palette.md +++ /dev/null @@ -1,3 +0,0 @@ -- CLI help strings for --json parameters are inconsistent ("Emit JSON output", "JSON output", "Emit JSON", missing help text). -- Based on repo rules: In the SEOCHO repository's CLI (`src/seocho/cli/`), the standard help string for JSON output arguments (`--json`) is `help="Emit JSON"`. -- Will standardize this as a clear UX/a11y improvement for CLI help text.