codex-pdf 1.7.1__tar.gz → 1.7.2__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.
Files changed (170) hide show
  1. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/CLAUDE.md +1 -1
  2. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/PKG-INFO +1 -1
  3. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/package.json +1 -1
  4. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/README.md +1 -1
  5. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/wrangler.toml +1 -1
  6. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/pyproject.toml +1 -1
  7. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/geom/path.py +5 -4
  8. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/version.py +1 -1
  9. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_geom.py +20 -11
  10. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/uv.lock +1 -1
  11. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/.cursor/rules/service-ownership.mdc +0 -0
  12. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/.github/workflows/ci.yml +0 -0
  13. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/.gitignore +0 -0
  14. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/.windsurf/rules/service-ownership.md +0 -0
  15. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/CONTRIBUTING.md +0 -0
  16. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/Dockerfile +0 -0
  17. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/LICENSE +0 -0
  18. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/Procfile +0 -0
  19. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/README.md +0 -0
  20. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/SECURITY.md +0 -0
  21. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/README.md +0 -0
  22. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/package-lock.json +0 -0
  23. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/src/color.ts +0 -0
  24. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/src/index.test.ts +0 -0
  25. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/src/index.ts +0 -0
  26. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/tsconfig.json +0 -0
  27. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/.github/workflows/deploy.yml +0 -0
  28. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/package-lock.json +0 -0
  29. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/package.json +0 -0
  30. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/src/cache_key.ts +0 -0
  31. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/src/env.ts +0 -0
  32. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/src/handlers/extract.ts +0 -0
  33. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/src/handlers/probe.ts +0 -0
  34. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/src/index.ts +0 -0
  35. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/src/sse_tee.ts +0 -0
  36. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/test/cache_key.test.ts +0 -0
  37. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/tsconfig.json +0 -0
  38. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/architecture.md +0 -0
  39. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/cli.md +0 -0
  40. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/contract.md +0 -0
  41. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/deploy.md +0 -0
  42. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/operations/codex-change-ripple.md +0 -0
  43. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/operations/marketing-deploy-template.md +0 -0
  44. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/parity.md +0 -0
  45. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/preflight-ingest.md +0 -0
  46. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/service-ownership-contract.md +0 -0
  47. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/railway.speculator.toml +0 -0
  48. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/railway.toml +0 -0
  49. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/audit/mislocated-closure.json +0 -0
  50. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/audit/produce_surface.json +0 -0
  51. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/dieline_calibration_report.json +0 -0
  52. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/codex_deep.json +0 -0
  53. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/codex_inventory.json +0 -0
  54. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/codex_summary.json +0 -0
  55. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/criterion4_parser_surface.json +0 -0
  56. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/pdfx4_deep.json +0 -0
  57. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/pdfx4_inventory.json +0 -0
  58. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/pdfx4_summary.json +0 -0
  59. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/render_baseline.json +0 -0
  60. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/viewer_essentials.json +0 -0
  61. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/CHANGELOG.md +0 -0
  62. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-annotation.schema.json +0 -0
  63. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-box.schema.json +0 -0
  64. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-color-space.schema.json +0 -0
  65. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-document.schema.json +0 -0
  66. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-font.schema.json +0 -0
  67. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-form-xobject.schema.json +0 -0
  68. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-image.schema.json +0 -0
  69. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-issue.schema.json +0 -0
  70. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-ocg.schema.json +0 -0
  71. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-output-intent.schema.json +0 -0
  72. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-page-object.schema.json +0 -0
  73. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-page.schema.json +0 -0
  74. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-preflight-report.schema.json +0 -0
  75. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-source.schema.json +0 -0
  76. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-spot-colorant.schema.json +0 -0
  77. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-transparency-tree.schema.json +0 -0
  78. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-trap-evidence.schema.json +0 -0
  79. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-warning.schema.json +0 -0
  80. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/probe.schema.json +0 -0
  81. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/scripts/calibrate_dieline_heuristics.py +0 -0
  82. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/scripts/parity_viewer_essentials.py +0 -0
  83. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/scripts/produce_surface_audit.py +0 -0
  84. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/__init__.py +0 -0
  85. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/__init__.py +0 -0
  86. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/auth.py +0 -0
  87. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/blob_store.py +0 -0
  88. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/cache.py +0 -0
  89. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/main.py +0 -0
  90. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/url_ingest.py +0 -0
  91. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/warmup.pdf +0 -0
  92. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/warmup.py +0 -0
  93. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/cli.py +0 -0
  94. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/client/__init__.py +0 -0
  95. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/client/http_client.py +0 -0
  96. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/__init__.py +0 -0
  97. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/alt_space.py +0 -0
  98. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/color_math.py +0 -0
  99. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/curated.py +0 -0
  100. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/data/pantone_reference.json +0 -0
  101. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/normalize.py +0 -0
  102. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/pantone.py +0 -0
  103. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/resolver.py +0 -0
  104. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/eval/__init__.py +0 -0
  105. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/eval/ps_type4.py +0 -0
  106. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/__init__.py +0 -0
  107. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/annotations.py +0 -0
  108. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/color.py +0 -0
  109. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/common.py +0 -0
  110. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/content_inventory.py +0 -0
  111. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/dieline_detector.py +0 -0
  112. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/document.py +0 -0
  113. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/fonts.py +0 -0
  114. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/forms.py +0 -0
  115. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/images.py +0 -0
  116. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/ocg.py +0 -0
  117. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/probe.py +0 -0
  118. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/signals.py +0 -0
  119. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/structure.py +0 -0
  120. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/summary.py +0 -0
  121. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/transparency.py +0 -0
  122. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/trapping.py +0 -0
  123. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/geom/__init__.py +0 -0
  124. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/geom/box.py +0 -0
  125. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/geom/matrix.py +0 -0
  126. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/geom/tile.py +0 -0
  127. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/geom/units.py +0 -0
  128. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/models/__init__.py +0 -0
  129. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/models/v1.py +0 -0
  130. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/parity.py +0 -0
  131. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/preflight_ingest/__init__.py +0 -0
  132. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/preflight_ingest/adapters.py +0 -0
  133. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/render/__init__.py +0 -0
  134. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/render/_common.py +0 -0
  135. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/render/content_stream.py +0 -0
  136. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/render/layer.py +0 -0
  137. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/render/page.py +0 -0
  138. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/render/separations.py +0 -0
  139. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/schema.py +0 -0
  140. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/speculator/__init__.py +0 -0
  141. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/speculator/__main__.py +0 -0
  142. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/speculator/consumer.py +0 -0
  143. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/conftest.py +0 -0
  144. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/fixtures/conforming/minimal.pdf +0 -0
  145. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/fixtures/generate_fixtures.py +0 -0
  146. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/fixtures/violating/no_output_intent.pdf +0 -0
  147. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/fixtures/violating/no_trim_box.pdf +0 -0
  148. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/fixtures/violating/no_xmp.pdf +0 -0
  149. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/fixtures/violating/pdf_1_4.pdf +0 -0
  150. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/golden/1.0.0/reference.json +0 -0
  151. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_alt_space.py +0 -0
  152. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_api.py +0 -0
  153. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_cache.py +0 -0
  154. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_cli_contract.py +0 -0
  155. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_client_routing.py +0 -0
  156. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_color.py +0 -0
  157. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_extract_analysis_signals.py +0 -0
  158. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_extract_structural.py +0 -0
  159. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_golden.py +0 -0
  160. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_golden_corpus.py +0 -0
  161. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_models.py +0 -0
  162. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_parity.py +0 -0
  163. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_pdf_sha256.py +0 -0
  164. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_preflight_ingest.py +0 -0
  165. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_produce_surface_audit.py +0 -0
  166. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_schema.py +0 -0
  167. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_schemas_all.py +0 -0
  168. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_speculator.py +0 -0
  169. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_summary_dieline.py +0 -0
  170. {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_summary_spot_colors.py +0 -0
@@ -25,7 +25,7 @@ For new products (Forge, Trap, Impose, Marks, etc.), map capabilities to one own
25
25
 
26
26
  When work spans layers, define a contract seam and keep logic in its owner service.
27
27
 
28
- ## Deployed surface (1.7.1)
28
+ ## Deployed surface (1.7.2)
29
29
 
30
30
  Codex now runs as **three services** in production. They share the
31
31
  same content-addressed cache key format
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-pdf
3
- Version: 1.7.1
3
+ Version: 1.7.2
4
4
  Summary: Authoritative, versioned PDF facts contract for Think Neverland tools.
5
5
  Author-email: Think Neverland <dev@thinkneverland.com>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@printwithsynergy/codex-client",
3
- "version": "1.7.1",
3
+ "version": "1.7.2",
4
4
  "description": "TypeScript client for the codex-pdf HTTP API. Mirrors the Python codex_pdf.client surface.",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-or-later",
@@ -10,7 +10,7 @@ the Railway codex-pdf service.
10
10
  - **Account**: `99aa3f9229469650a746a7d39ac58448` (`Quincy@thinkneverland.com's Account`)
11
11
  - **KV namespace `CACHE`**: `89a21ce1937046018a3d9d38f4e763ff` (preview `a4856d6f3b244087b907c189c2a2277d`)
12
12
  - **Origin** (`CODEX_ORIGIN_URL`): `https://codex-pdf-lint-sidecar-production.up.railway.app`
13
- - **Codex version pinned**: `1.7.1` (`CODEX_VERSION` var — bump on origin release)
13
+ - **Codex version pinned**: `1.7.2` (`CODEX_VERSION` var — bump on origin release)
14
14
  - **TTLs**: probe 24 h, Phase 1 24 h, Phase 2 7 d
15
15
 
16
16
  ## What it caches
@@ -23,7 +23,7 @@ CODEX_ORIGIN_URL = "https://codex-pdf-lint-sidecar-production.up.railway.app"
23
23
  # Codex package VERSION at deploy time. MUST match the origin's
24
24
  # `codex_pdf.version.VERSION` so KV keys line up. Bump on every
25
25
  # origin release.
26
- CODEX_VERSION = "1.7.1"
26
+ CODEX_VERSION = "1.7.2"
27
27
  # TTL (seconds) for cached SSE event payloads.
28
28
  PROBE_TTL = "86400" # 24 h — small payload, refresh daily
29
29
  PHASE1_TTL = "86400" # 24 h — matches origin Redis TTL
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "codex-pdf"
7
- version = "1.7.1"
7
+ version = "1.7.2"
8
8
  description = "Authoritative, versioned PDF facts contract for Think Neverland tools."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -214,9 +214,6 @@ def _polygon_corners(box: Box) -> tuple[Point, Point, Point, Point]:
214
214
  )
215
215
 
216
216
 
217
- _SCALE = 1_000 # pyclipr integer scale factor for offset operations
218
-
219
-
220
217
  def polygon_offset(
221
218
  path: Path,
222
219
  distance: float,
@@ -276,7 +273,11 @@ def polygon_offset(
276
273
  for ring in path.rings:
277
274
  scaled = _scale_polygon(ring)
278
275
  po.addPath(scaled, jt, et)
279
- result_paths = po.execute(distance * _SCALE)
276
+ # Coords are scaled into integer space by `_scale_polygon` (×_CLIPPER_SCALE);
277
+ # the offset distance MUST use the same factor or it gets diluted by the
278
+ # ratio. Prior to 1.7.2 this used a private 1_000 constant that left a 1000×
279
+ # gap, so a 10-pt request only grew by 0.01 pt.
280
+ result_paths = po.execute(distance * _CLIPPER_SCALE)
280
281
  rings = [_unscale_polygon(p) for p in result_paths]
281
282
  return Path(rings=tuple(rings))
282
283
 
@@ -38,5 +38,5 @@ or unreachable Redis service can never crash the codex API.
38
38
  1.3.0 (prior): SSRF hardening + /v1/walk/type4 endpoint.
39
39
  """
40
40
 
41
- VERSION = "1.7.1"
41
+ VERSION = "1.7.2"
42
42
  __version__ = VERSION
@@ -140,27 +140,36 @@ def test_polygon_intersect_triangles_via_clipper() -> None:
140
140
 
141
141
  @pytest.mark.skipif(not HAS_PYCLIPR, reason="pyclipr is required for polygon offset")
142
142
  def test_polygon_offset_triangle_spread_and_choke() -> None:
143
- """Regression for pyclipr 0.1.8 ClipperOffset kwarg removal.
144
-
145
- Pre-fix this raised ``TypeError: __init__(): incompatible constructor
146
- arguments`` because ``ClipperOffset(miterLimit=...)`` is no longer
147
- accepted the miter limit moved to a property set after construction.
148
- Rectangular paths bypassed pyclipr entirely (rect fast-path), so the
149
- bug was invisible without a triangle / pentagon exercise.
143
+ """Triangle offset returns correctly-sized rings.
144
+
145
+ Covers two bugs the pre-1.7.x codex had:
146
+
147
+ 1. ``ClipperOffset(miterLimit=...)`` raised ``TypeError`` under pyclipr
148
+ 0.1.8 (constructor dropped all kwargs). Triggered only on non-
149
+ rectangular paths because rect inputs hit the fast-path bypass.
150
+ 2. The integer-scale factor used for the offset distance (1e3) didn't
151
+ match the coord scale (1e6), so the effective offset was ×1000
152
+ smaller than the caller asked for — a 10-pt request grew the bbox
153
+ by ~0.01 pt. Assertions below check magnitude, not just direction,
154
+ to catch a future re-introduction.
150
155
  """
151
156
  triangle = Path.from_polygons([[(0.0, 0.0), (100.0, 0.0), (50.0, 100.0)]])
152
157
 
153
158
  spread = polygon_offset(triangle, 10.0)
154
159
  assert len(spread.rings) == 1
155
160
  sb = spread.bbox()
156
- assert sb.x0 < 0.0 and sb.y0 < 0.0
157
- assert sb.x1 > 100.0 and sb.y1 > 100.0
161
+ # A 10-pt spread should push the bbox at least ~9 pt outward on each
162
+ # side; miter-join geometry on a sharp triangle apex may extend the y
163
+ # max even further, so we only bound the *minimum* growth.
164
+ assert sb.x0 <= -9.0 and sb.y0 <= -9.0, f"spread bbox not wide enough: {sb}"
165
+ assert sb.x1 >= 109.0 and sb.y1 >= 109.0, f"spread bbox not tall enough: {sb}"
158
166
 
159
167
  choke = polygon_offset(triangle, -5.0)
160
168
  assert choke.rings
161
169
  cb = choke.bbox()
162
- assert cb.x0 > 0.0 and cb.y0 > 0.0
163
- assert cb.x1 < 100.0 and cb.y1 < 100.0
170
+ # 5-pt choke should pull each side inward by ≥ ~4 pt.
171
+ assert cb.x0 >= 4.0 and cb.y0 >= 4.0, f"choke bbox not inset enough: {cb}"
172
+ assert cb.x1 <= 96.0 and cb.y1 <= 96.0, f"choke bbox not inset enough: {cb}"
164
173
 
165
174
 
166
175
  # ---------------------------------------------------------------------------
@@ -65,7 +65,7 @@ wheels = [
65
65
 
66
66
  [[package]]
67
67
  name = "codex-pdf"
68
- version = "1.7.0"
68
+ version = "1.7.1"
69
69
  source = { editable = "." }
70
70
  dependencies = [
71
71
  { name = "fastapi" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes