openom-cli 0.1.2__tar.gz → 0.1.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.5
2
2
  Name: openom-cli
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: openOM CLI - the `om` command over openom-core. Zero inference.
5
5
  Project-URL: Homepage, https://openom.app
6
6
  Project-URL: Documentation, https://openom.app/docs/
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "openom-cli"
7
- version = "0.1.2"
7
+ version = "0.1.3"
8
8
  description = "openOM CLI - the `om` command over openom-core. Zero inference."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -197,8 +197,17 @@ def _load_json(path: Path) -> dict[str, Any]:
197
197
  # parse_hardened enforces the same §J read invariants the embed/MCP paths do - reject duplicate
198
198
  # keys and over-deep nesting - degrading a pathological payload to a structured OM-IO error
199
199
  # (caught by _guard -> exit 3) instead of a RecursionError traceback.
200
- text = sys.stdin.read() if str(path) == "-" else path.read_text(encoding="utf-8")
201
- return cast("dict[str, Any]", _parse_hardened(text))
200
+ raw = sys.stdin.buffer.read() if str(path) == "-" else path.read_bytes()
201
+ if raw[:5].startswith(b"%PDF"):
202
+ # The natural first mistake: pointing `validate` (or another JSON verb) at an OM PDF. Give a
203
+ # plain hint toward the right verb instead of a cryptic UnicodeDecodeError on binary bytes.
204
+ typer.echo(
205
+ f"error: {path} looks like a PDF, not a JSON payload. To read the data embedded in an "
206
+ f"OM PDF use `om read {path}`; `validate` checks a deal.json (see `om init`).",
207
+ err=True,
208
+ )
209
+ raise typer.Exit(3)
210
+ return cast("dict[str, Any]", _parse_hardened(raw.decode("utf-8")))
202
211
 
203
212
 
204
213
  def _emit(obj: Any) -> None:
@@ -486,6 +486,15 @@ def test_validate_deeply_nested_json_degrades_cleanly(tmp_path: Path) -> None:
486
486
  assert "OM-IO-STRUCTURE" in r.output
487
487
 
488
488
 
489
+ def test_validate_on_a_pdf_gives_a_useful_hint(tmp_path: Path) -> None:
490
+ # The natural first mistake - validate a PDF - must point at `om read`, not die on a raw
491
+ # UnicodeDecodeError decoding binary bytes.
492
+ pdf = _base_pdf(tmp_path / "deal.pdf")
493
+ r = runner.invoke(app, ["validate", str(pdf)])
494
+ assert r.exit_code == 3
495
+ assert "looks like a PDF" in r.output and "om read" in r.output
496
+
497
+
489
498
  def test_check_payload_json(tmp_path: Path) -> None:
490
499
  # Consistency tier only (no schema): the valid sample is internally consistent -> exit 0.
491
500
  r = runner.invoke(app, ["check", str(SPEC / "samples" / "valid-stnl.json")])
File without changes
File without changes