exstruct 0.7.0__tar.gz → 0.8.0__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 (87) hide show
  1. {exstruct-0.7.0 → exstruct-0.8.0}/PKG-INFO +185 -148
  2. {exstruct-0.7.0 → exstruct-0.8.0}/README.md +184 -147
  3. {exstruct-0.7.0 → exstruct-0.8.0}/pyproject.toml +1 -1
  4. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/__init__.py +183 -47
  5. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/cli/availability.py +1 -1
  6. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/cli/edit.py +525 -411
  7. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/cli/main.py +108 -27
  8. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/backends/__init__.py +2 -0
  9. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/backends/base.py +2 -2
  10. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/backends/com_backend.py +2 -2
  11. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/backends/libreoffice_backend.py +95 -7
  12. exstruct-0.8.0/src/exstruct/core/backends/ooxml_backend.py +95 -0
  13. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/libreoffice.py +108 -14
  14. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/ooxml_drawing.py +238 -17
  15. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/pipeline.py +68 -11
  16. exstruct-0.8.0/src/exstruct/edit/__init__.py +281 -0
  17. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/engine.py +206 -17
  18. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/errors.py +1 -0
  19. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/models/__init__.py +2 -2
  20. exstruct-0.7.0/src/exstruct/edit/__init__.py +0 -128
  21. {exstruct-0.7.0 → exstruct-0.8.0}/LICENSE +0 -0
  22. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/constraints.py +0 -0
  23. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/__init__.py +0 -0
  24. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/_libreoffice_bridge.py +0 -0
  25. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/backends/openpyxl_backend.py +0 -0
  26. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/cells.py +0 -0
  27. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/charts.py +0 -0
  28. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/integrate.py +0 -0
  29. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/logging_utils.py +0 -0
  30. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/modeling.py +0 -0
  31. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/ranges.py +0 -0
  32. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/shapes.py +0 -0
  33. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/core/workbook.py +0 -0
  34. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/a1.py +0 -0
  35. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/api.py +0 -0
  36. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/chart_types.py +0 -0
  37. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/engine/__init__.py +0 -0
  38. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/engine/openpyxl_engine.py +0 -0
  39. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/engine/xlwings_engine.py +0 -0
  40. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/errors.py +0 -0
  41. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/internal.py +0 -0
  42. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/models.py +0 -0
  43. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/normalize.py +0 -0
  44. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/op_schema.py +0 -0
  45. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/output_path.py +0 -0
  46. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/runtime.py +0 -0
  47. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/service.py +0 -0
  48. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/specs.py +0 -0
  49. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/edit/types.py +0 -0
  50. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/io/__init__.py +0 -0
  51. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/io/serialize.py +0 -0
  52. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/__init__.py +0 -0
  53. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/chunk_reader.py +0 -0
  54. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/extract_runner.py +0 -0
  55. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/io.py +0 -0
  56. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/op_schema.py +0 -0
  57. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/__init__.py +0 -0
  58. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/chart_types.py +0 -0
  59. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/engine/__init__.py +0 -0
  60. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/engine/base.py +0 -0
  61. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/engine/openpyxl_engine.py +0 -0
  62. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/engine/xlwings_engine.py +0 -0
  63. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/internal.py +0 -0
  64. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/models.py +0 -0
  65. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/normalize.py +0 -0
  66. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/ops/__init__.py +0 -0
  67. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/ops/common.py +0 -0
  68. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/ops/openpyxl_ops.py +0 -0
  69. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/ops/xlwings_ops.py +0 -0
  70. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/runtime.py +0 -0
  71. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/service.py +0 -0
  72. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/specs.py +0 -0
  73. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch/types.py +0 -0
  74. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/patch_runner.py +0 -0
  75. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/render_runner.py +0 -0
  76. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/server.py +0 -0
  77. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/shared/__init__.py +0 -0
  78. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/shared/a1.py +0 -0
  79. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/shared/output_path.py +0 -0
  80. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/sheet_reader.py +0 -0
  81. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/tools.py +0 -0
  82. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/mcp/validate_input.py +0 -0
  83. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/models/maps.py +0 -0
  84. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/models/types.py +0 -0
  85. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/py.typed +0 -0
  86. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/render/__init__.py +0 -0
  87. {exstruct-0.7.0 → exstruct-0.8.0}/src/exstruct/render/subprocess_worker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: exstruct
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: Excel to structured JSON (tables, shapes, charts) for LLM/RAG pipelines
5
5
  Keywords: excel,structure,data,exstruct
6
6
  Author: harumiWeb
@@ -97,38 +97,29 @@ editing workflows through a shared core. It provides extraction APIs, a
97
97
  JSON-first editing CLI, and an MCP server for host-managed integrations, with
98
98
  options tuned for LLM/RAG preprocessing, reviewable edit flows, and local
99
99
  automation.
100
-
101
- - In COM/Excel environments (Windows), it performs rich extraction.
102
- - In non-COM environments (Linux/macOS):
103
- - if the LibreOffice runtime is available, it performs best-effort extraction for cells, table candidates, shapes, connectors, and charts
104
- - otherwise, it safely falls back to cells + table candidates + print areas
105
-
100
+
101
+ - In COM/Excel environments (Windows), it performs rich extraction.
102
+ - In non-COM environments (Linux/macOS):
103
+ - direct OOXML parsing extracts cells, shapes, charts, table candidates, and print areas on a best-effort basis
104
+ - if the LibreOffice runtime is available, cells, table candidates, shapes, and charts are also extracted on a best-effort basis
105
+
106
106
  Detection heuristics, editing workflows, and output modes are adjustable for
107
107
  LLM/RAG pipelines and local automation.
108
108
 
109
- ## Choose an Interface
110
-
111
- | Use case | Recommended interface | Why |
112
- | --- | --- | --- |
113
- | Write direct Python Excel-editing code | `openpyxl` / `xlwings` | Usually the better fit for imperative Python editing. Reach for `exstruct.edit` only when you specifically want ExStruct's patch contract in Python. |
114
- | Run local operator or AI-agent edit workflows | `exstruct patch`, `make`, `ops`, `validate` | Canonical operational interface; JSON-first and dry-run friendly. |
115
- | Run sandboxed or host-managed integrations | `exstruct-mcp` / MCP tools | Integration / compatibility layer that owns `PathPolicy`, transport, and artifact behavior. |
109
+ ## Main Features
116
110
 
117
- Extraction keeps the existing top-level Python API (`extract`, `process_excel`,
118
- `ExStructEngine`) and the legacy `exstruct INPUT.xlsx ...` CLI entrypoint.
119
-
120
- ## Main Features
121
-
122
- - **Excel -> structured JSON**: outputs cells, shapes, charts, SmartArt, table candidates, merged-cell ranges, print areas, and auto page-break areas by sheet or by area.
123
- - **Output modes**: `light` (cells + table candidates + print areas only), `libreoffice` (best-effort non-COM mode for `.xlsx/.xlsm`; adds merged cells, shapes, connectors, and charts when the LibreOffice runtime is available), `standard` (Excel COM mode with texted shapes + arrows, charts, SmartArt, and merged-cell ranges), `verbose` (all shapes with width/height plus cell hyperlinks).
124
- - **Formula extraction**: emits `formulas_map` (formula string -> cell coordinates) via openpyxl/COM. It is enabled by default in `verbose` and can be controlled with `include_formulas_map`.
111
+ - **Excel -> structured JSON**: outputs cells, shapes, charts, SmartArt, table candidates, merged-cell ranges, print areas, and auto page-break areas by sheet or by area.
112
+ - **Output modes**:
113
+ - `light`: cells + table candidates + print areas + shapes/charts (best-effort via direct OOXML parsing)
114
+ - `libreoffice`: best-effort non-COM mode for `.xlsx/.xlsm`. When the LibreOffice runtime is available, it adds merged cells, shapes, connectors, and charts
115
+ - `standard`: Excel COM mode with texted shapes + arrows, charts, SmartArt, and merged-cell ranges
116
+ - `verbose`: outputs all shapes with width/height and also emits cell hyperlinks
117
+ - **Formula extraction**: emits `formulas_map` (formula string -> cell coordinates) via openpyxl/COM. It is enabled by default in `verbose` and can be controlled with `include_formulas_map`.
125
118
  - **Formats**: JSON (compact by default, `--pretty` for formatting), YAML, and TOON (optional dependencies).
126
- - **Backend metadata is opt-in**: shape/chart `provenance`, `approximation_level`, and `confidence` are omitted from serialized output by default. Enable them with `--include-backend-metadata` or `include_backend_metadata=True`.
127
119
  - **Workbook editing interfaces**: use the editing CLI for primary ExStruct edit flows, keep MCP for host-owned safety controls, and use `exstruct.edit` only when you need the same patch contract from Python.
128
120
  - **Table detection tuning**: heuristics can be adjusted dynamically through the API.
129
- - **Hyperlink extraction**: in `verbose` mode, or with `include_cell_links=True`, cell links are emitted in `links`.
130
- - **CLI rendering**: in `standard` / `verbose`, PDF and sheet images can be generated when Excel COM is available.
131
- - **Safe fallback**: if Excel COM or the LibreOffice runtime is unavailable, the process does not crash and falls back to cells + table candidates + print areas.
121
+ - **Hyperlink extraction**: in `verbose` mode, or with `include_cell_links=True`, cell links are emitted in `links`.
122
+ - **Safe fallback**: if Excel COM or the LibreOffice runtime is unavailable, the process does not crash and falls back to direct OOXML parsing.
132
123
 
133
124
  ## Installation
134
125
 
@@ -143,14 +134,12 @@ Optional extras:
143
134
  - Rendering (PDF/PNG): Excel + `pip install pypdfium2 pillow` (`mode=libreoffice` is not supported)
144
135
  - Install everything at once: `pip install exstruct[yaml,toon,render]`
145
136
 
146
- Platform note:
147
-
148
- - Full COM extraction for shapes/charts targets Windows + Excel (xlwings/COM). On Linux/macOS/server environments, use `mode=libreoffice` as the best-effort rich mode or `mode=light` for minimal extraction. `.xls` is not supported in `mode=libreoffice`.
149
- - On Debian/Ubuntu/WSL, install LibreOffice together with `python3-uno`. ExStruct probes a compatible system Python automatically for `mode=libreoffice`; if your environment needs an explicit interpreter, set `EXSTRUCT_LIBREOFFICE_PYTHON_PATH=/usr/bin/python3`.
150
- - LibreOffice Python detection now runs the bundled bridge in `--probe` mode before selection. An incompatible `EXSTRUCT_LIBREOFFICE_PYTHON_PATH` fails fast instead of surfacing a delayed bridge `SyntaxError` during extraction.
151
- - If the isolated temporary LibreOffice profile fails before the UNO socket becomes ready, ExStruct retries once with the shared/default LibreOffice profile as a compatibility fallback and reports per-attempt startup detail if both launches fail.
152
- - GitHub Actions includes dedicated LibreOffice smoke jobs on `ubuntu-24.04` and `windows-2025`. Linux installs `libreoffice` + `python3-uno`; Windows installs `libreoffice-fresh`, sets `EXSTRUCT_LIBREOFFICE_PATH`, and both jobs run `tests/core/test_libreoffice_smoke.py` with `RUN_LIBREOFFICE_SMOKE=1`.
153
-
137
+ Platform note:
138
+
139
+ - On Debian/Ubuntu/WSL, install LibreOffice together with `python3-uno`. ExStruct probes a compatible system Python automatically for `mode=libreoffice`; if your environment needs an explicit interpreter, set `EXSTRUCT_LIBREOFFICE_PYTHON_PATH=/usr/bin/python3`.
140
+ - LibreOffice Python detection now runs the bundled bridge in `--probe` mode before selection. An incompatible `EXSTRUCT_LIBREOFFICE_PYTHON_PATH` fails fast instead of surfacing a delayed bridge `SyntaxError` during extraction.
141
+ - If the isolated temporary LibreOffice profile fails before the UNO socket becomes ready, ExStruct retries once with the shared/default LibreOffice profile as a compatibility fallback and reports per-attempt startup detail if both launches fail.
142
+
154
143
  ## Quick Start CLI
155
144
 
156
145
  ```bash
@@ -159,19 +148,18 @@ exstruct input.xlsx -o out.json --pretty # write pretty JSON to a file
159
148
  exstruct input.xlsx --format yaml # YAML (requires pyyaml)
160
149
  exstruct input.xlsx --format toon # TOON (requires python-toon)
161
150
  exstruct input.xlsx --sheets-dir sheets/ # write one file per sheet
162
- exstruct input.xlsx --auto-page-breaks-dir auto_areas/ # COM only; shown only when available
163
- exstruct input.xlsx --alpha-col # output column keys as A, B, ..., AA
164
- exstruct input.xlsx --include-backend-metadata # include shape/chart backend metadata
165
- exstruct input.xlsx --mode light # cells + table candidates only
166
- exstruct input.xlsx --mode libreoffice # best-effort extraction of shapes/connectors/charts without COM
151
+ exstruct input.xlsx --auto-page-breaks-dir auto_areas/ # always shown; execution requires standard/verbose + Excel COM
152
+ exstruct input.xlsx --alpha-col # output column keys as A, B, ..., AA
153
+ exstruct input.xlsx --include-backend-metadata # include shape/chart backend metadata
154
+ exstruct input.xlsx --mode light # cells + table candidates + best-effort OOXML shapes/charts
155
+ exstruct input.xlsx --mode libreoffice # best-effort extraction of shapes/connectors/charts without COM
167
156
  exstruct input.xlsx --pdf --image # PDF and PNGs (Excel COM required)
168
157
  ```
169
158
 
170
- Auto page-break export is available from both the API and the CLI when Excel/COM is available. The CLI exposes `--auto-page-breaks-dir` only in COM-capable environments.
171
- `mode=libreoffice` rejects `--pdf`, `--image`, and `--auto-page-breaks-dir` early. Use `standard` or `verbose` with Excel COM for those features.
172
- By default, the CLI keeps legacy 0-based numeric string column keys (`"0"`, `"1"`, ...). Use `--alpha-col` when you need Excel-style keys (`"A"`, `"B"`, ...).
173
- By default, serialized shape/chart output omits backend metadata (`provenance`, `approximation_level`, `confidence`) to reduce token usage. Use `--include-backend-metadata` or the corresponding Python/MCP option when you need it.
174
- Note: MCP `exstruct_extract` defaults to `options.alpha_col=true`, which differs from the CLI default (`false`).
159
+ Auto page-break export is available from both the API and the CLI when Excel/COM is available. The CLI always exposes `--auto-page-breaks-dir`, but validates it at execution time.
160
+ `mode=libreoffice` rejects `--pdf`, `--image`, and `--auto-page-breaks-dir` early, and `mode=light` also rejects `--auto-page-breaks-dir`. Use `standard` or `verbose` with Excel COM for those features.
161
+ By default, the CLI keeps legacy 0-based numeric string column keys (`"0"`, `"1"`, ...). Use `--alpha-col` when you need Excel-style keys (`"A"`, `"B"`, ...).
162
+ By default, serialized shape/chart output omits backend metadata (`provenance`, `approximation_level`, `confidence`) to reduce token usage. Use `--include-backend-metadata` or the corresponding Python/MCP option when you need it.
175
163
 
176
164
  ## Quick Start Editing CLI
177
165
 
@@ -185,11 +173,8 @@ exstruct validate --input book.xlsx --pretty
185
173
  ```
186
174
 
187
175
  - `patch` and `make` print JSON `PatchResult` to stdout.
188
- - This is the canonical operational / agent interface for workbook editing.
189
176
  - `ops list` / `ops describe` expose the public patch-op schema.
190
177
  - `validate` reports workbook readability (`is_readable`, `warnings`, `errors`).
191
- - Phase 2 keeps the legacy extraction CLI unchanged; it does not add
192
- `exstruct extract` or interactive safety flags yet.
193
178
 
194
179
  Recommended edit flow:
195
180
 
@@ -199,6 +184,32 @@ Recommended edit flow:
199
184
  4. If you keep `--backend auto`, inspect `PatchResult.engine`; on Windows/Excel hosts the real apply may switch to COM.
200
185
  5. Re-run without `--dry-run` only after the result is acceptable.
201
186
 
187
+ ## ExStruct CLI Skill
188
+
189
+ ExStruct also ships one repo-owned Skill for agents that should follow the
190
+ editing CLI safely instead of rediscovering the workflow each time.
191
+
192
+ Canonical repo source:
193
+
194
+ - `.agents/skills/exstruct-cli/`
195
+
196
+ You can install it with the following single command:
197
+
198
+ ```bash
199
+ npx skills add harumiWeb/exstruct/.agents/skills --skill exstruct-cli
200
+ ```
201
+
202
+ If your runtime cannot use `npx skills add`, place the same folder manually
203
+ into a local skill directory that discovers `SKILL.md`-based skills.
204
+
205
+ Use this Skill when the agent needs help choosing between `patch`, `make`,
206
+ `validate`, `ops list`, and `ops describe`, or when it should follow the safe
207
+ `validate -> dry-run -> inspect -> apply -> verify` workflow.
208
+
209
+ Example prompt for agents:
210
+
211
+ > Use `$exstruct-cli` to choose the right ExStruct editing CLI command, follow a safe validate/dry-run/inspect workflow, and explain any backend constraints for this workbook task.
212
+
202
213
  ## MCP Server (stdio)
203
214
 
204
215
  MCP is the integration / compatibility layer around the same editing core. Use
@@ -206,11 +217,6 @@ it when you need host-managed path restrictions, transport mapping, artifact
206
217
  mirroring, or approval-aware agent execution. For ordinary Python workbook
207
218
  editing, `openpyxl` / `xlwings` are usually a better fit. For local shell or
208
219
  agent workflows, prefer the editing CLI.
209
-
210
- If you previously used `exstruct_patch` / `exstruct_make` only because editing
211
- was MCP-first, migrate new local workflows to `exstruct patch` or
212
- `exstruct make` unless you specifically need MCP host controls or the shared
213
- patch contract inside Python.
214
220
 
215
221
  ### Quick Start with `uvx` (recommended)
216
222
 
@@ -236,51 +242,22 @@ pip install exstruct[mcp]
236
242
  exstruct-mcp --root C:\data --log-file C:\logs\exstruct-mcp.log --on-conflict rename
237
243
  ```
238
244
 
239
- Available tools:
240
-
241
- - `exstruct_extract`
242
- - `exstruct_capture_sheet_images`
243
- - `exstruct_make`
244
- - `exstruct_patch`
245
- - `exstruct_read_json_chunk`
246
- - `exstruct_read_range`
247
- - `exstruct_read_cells`
248
- - `exstruct_read_formulas`
249
- - `exstruct_validate_input`
250
-
251
- Notes:
252
-
253
- - `exstruct_capture_sheet_images` is COM-only (Experimental) and supports optional `sheet` / `range` targeting (`A1:B2`, `Sheet1!A1:B2`, `'Sheet 1'!A1:B2`). When `out_dir` is omitted, it creates a unique `<workbook_stem>_images` directory under MCP `--root`.
254
- - MCP server startup defaults `EXSTRUCT_RENDER_SUBPROCESS=1` via `setdefault`. If you want in-process execution instead, set `EXSTRUCT_RENDER_SUBPROCESS=0` before launching the server.
255
- - Timeout tuning for `exstruct_capture_sheet_images`: `EXSTRUCT_MCP_CAPTURE_SHEET_IMAGES_TIMEOUT_SEC` (overall tool timeout), `EXSTRUCT_RENDER_SUBPROCESS_STARTUP_TIMEOUT_SEC` (worker startup), `EXSTRUCT_RENDER_SUBPROCESS_JOIN_TIMEOUT_SEC` (primary wait budget), and `EXSTRUCT_RENDER_SUBPROCESS_RESULT_TIMEOUT_SEC` (post-exit grace).
256
- - Subprocess failures return `stage=startup|join|result|worker`, which lets MCP clients distinguish bootstrap failures, timeouts, and worker-side rendering failures.
257
- - Trade-off of `EXSTRUCT_RENDER_SUBPROCESS=1`: extra subprocess startup/coordination overhead and more dependency on worker-side module resolution.
258
- - Trade-off of `EXSTRUCT_RENDER_SUBPROCESS=0`: weaker crash isolation and higher memory pressure risk in long-running processes.
259
- - Logs are written to stderr, and optionally to `--log-file`, to keep stdio responses clean.
260
- - On Windows with Excel, `standard` / `verbose` use COM for the richest extraction.
261
- - On Linux/macOS/server environments, `libreoffice` is the best-effort rich mode. It is not a strict subset of COM output; shapes, connectors, and charts are reconstructed from LibreOffice + OOXML metadata and may differ in fidelity.
262
- - In v1, `libreoffice` does not render PDFs/PNGs and does not compute auto page-break areas.
263
- - `exstruct_patch` supports `backend` selection.
264
- - `auto` (default): prefer COM when available, otherwise openpyxl
265
- - `com`: force COM (`dry_run` / `return_inverse_ops` / `preflight_formula_check` are not allowed)
266
- - `openpyxl`: force openpyxl (`.xls` is not supported)
267
- - `create_chart` is COM-only. Requests that include `create_chart` cannot use `backend="openpyxl"`, and they also reject `dry_run`, `return_inverse_ops`, and `preflight_formula_check`.
268
- - `create_chart` supports `chart_type` values `line`, `column`, `bar`, `area`, `pie`, `doughnut`, `scatter`, and `radar` (aliases: `column_clustered`, `bar_clustered`, `xy_scatter`, `donut`).
269
- - `create_chart` accepts either a single range string or `list[str]` for `data_range`, and both `data_range` and `category_range` support sheet-qualified ranges such as `Sheet2!A1:B10` and `'Sales Data'!A1:B10`.
270
- - `create_chart` also supports explicit titles with `chart_title`, `x_axis_title`, and `y_axis_title`.
271
- - `create_chart` and `apply_table_style` can be combined in one request when the backend resolves to COM (`backend="com"` or COM-capable `backend="auto"`).
272
- - For stable COM execution of `apply_table_style` on Windows, make sure desktop Excel is installed and runnable, and that the target `range` is a contiguous A1 range including the header row.
273
- - `exstruct_patch` error details may include `error_code`, `failed_field`, and `raw_com_message`. Table-related codes include `table_style_invalid`, `list_object_add_failed`, and `com_api_missing`.
274
- - `exstruct_patch` responses include the actual backend in `engine` (`com` / `openpyxl`). `restore_design_snapshot` remains openpyxl-only.
275
- - Use `exstruct_make` for creating new workbooks and `exstruct_patch` for editing existing ones.
276
- - `exstruct_make` creates a new workbook and applies `ops` in one call (`out_path` required, `ops` optional).
277
- - supported extensions: `.xlsx` / `.xlsm` / `.xls`
278
- - the initial sheet name is normalized to `Sheet1`
279
- - `.xls` requires COM, so `backend=openpyxl` is not allowed
280
-
281
- MCP setup guide for each AI agent:
282
-
283
- [MCP Server](https://harumiweb.github.io/exstruct/mcp/)
245
+ Available tools:
246
+
247
+ | Tool name | Description |
248
+ | ------------------------------- | -------------------------------------- |
249
+ | `exstruct_extract` | Extracts data from a workbook. |
250
+ | `exstruct_capture_sheet_images` | Captures sheet images. |
251
+ | `exstruct_make` | Creates a new workbook. |
252
+ | `exstruct_patch` | Applies editing patches to a workbook. |
253
+ | `exstruct_read_json_chunk` | Reads extracted JSON chunks. |
254
+ | `exstruct_read_range` | Reads cells from a specified range. |
255
+ | `exstruct_read_cells` | Reads data cell by cell. |
256
+ | `exstruct_read_formulas` | Reads cell formulas. |
257
+ | `exstruct_validate_input` | Validates input data. |
258
+
259
+ For more details and API usage, see the documentation site:
260
+ [MCP Server](https://harumiweb.github.io/exstruct/mcp/)
284
261
 
285
262
  ## Quick Start Python Extraction
286
263
 
@@ -349,7 +326,7 @@ engine_auto.export(wb_auto, Path("out_with_auto.json"))
349
326
  export_auto_page_breaks(wb_auto, "auto_areas", fmt="json", pretty=True)
350
327
  ```
351
328
 
352
- **Note (non-COM environments):** even when Excel COM is unavailable, cells + `table_candidates` are still returned, but `shapes` / `charts` will be empty.
329
+ **Note (non-COM environments):** even when Excel COM is unavailable, cells + `table_candidates` are still returned, and `.xlsx` / `.xlsm` keep best-effort OOXML `shapes` / `charts` when available.
353
330
 
354
331
  ## Table Detection Parameters
355
332
 
@@ -364,18 +341,18 @@ set_table_detection_params(
364
341
  )
365
342
  ```
366
343
 
367
- Higher values reduce false positives. Lower values reduce missed detections.
368
-
369
- ## Output Modes
370
-
371
- - **light**: cells + table candidates only (no COM required).
372
- - **standard**: texted shapes + arrows, charts (when COM is available), table candidates, and merged-cell ranges. Cell hyperlinks are emitted only when `include_cell_links=True`.
373
- - **verbose**: all shapes (with width/height), charts, table candidates, merged-cell ranges, hyperlinks, `colors_map`, and `formulas_map`.
374
-
375
- ## Error Handling / Fallback
376
-
377
- - If Excel COM is unavailable, extraction falls back to cells + table candidates automatically, and shapes/charts remain empty.
378
- - If shape extraction fails, ExStruct still returns cells + table candidates and only emits a warning.
344
+ Higher values reduce false positives. Lower values reduce missed detections.
345
+
346
+ ## Output Modes
347
+
348
+ - **light**: cells + table candidates + best-effort OOXML shapes/connectors/charts for `.xlsx` / `.xlsm` (no COM required).
349
+ - **standard**: texted shapes + arrows, charts (when COM is available), and table candidates. Cell hyperlinks are emitted only when `include_cell_links=True`.
350
+ - **verbose**: all shapes, charts, `table_candidates`, hyperlinks, and `colors_map`.
351
+
352
+ ## Error Handling / Fallback
353
+
354
+ - If Excel COM is unavailable, extraction falls back to cells + table candidates automatically; `.xlsx` / `.xlsm` still preserve best-effort OOXML shapes/charts when available.
355
+ - If a rich-extraction step fails, ExStruct still returns cells + table candidates and keeps any already recovered best-effort artifacts where safe.
379
356
  - The CLI writes errors to stdout/stderr and exits with a non-zero status on failure.
380
357
 
381
358
  ## Optional Rendering
@@ -393,12 +370,13 @@ This writes `<output>.pdf` and PNG files under `<output>_images/`.
393
370
  To show how far exstruct can structure Excel, we parse an Excel workbook that combines the following three elements on a single sheet and show an LLM reasoning example based on the JSON output.
394
371
 
395
372
  - a table (sales data)
396
- - a line chart
397
- - a flowchart built only with shapes
398
-
399
- (The image below is the actual sample Excel sheet.)
400
- <img width="1842" height="1242" alt="demo_sheet" src="https://github.com/user-attachments/assets/91f32b64-02a9-4269-a13f-9909e6e5b06f" />
401
- Sample Excel: `sample/sample.xlsx`
373
+ - a line chart
374
+ - a flowchart built only with shapes
375
+
376
+ The image below is the actual sample Excel sheet.
377
+ ![Sample Excel](docs/assets/demo_sheet.png)
378
+
379
+ Sample Excel: `sample/sample.xlsx`
402
380
 
403
381
  ### 1. Input: Excel Sheet Overview
404
382
 
@@ -511,10 +489,10 @@ Below is a shortened JSON output example from parsing the workbook above.
511
489
  }
512
490
  ```
513
491
 
514
- ### 3. How AI (Copilot / LLM) interprets the JSON
515
-
516
- ````md
517
- Below is a Markdown reconstruction of the Excel workbook. It expresses the table, chart, and flowchart as separate structures.
492
+ ### 3. How AI (Copilot / LLM) interprets the JSON
493
+
494
+ ````md
495
+ Below is a Markdown reconstruction of the Excel workbook. It expresses the table, chart, and flowchart as separate structures.
518
496
 
519
497
  ---
520
498
 
@@ -572,11 +550,11 @@ flowchart TD
572
550
  ```
573
551
  ````
574
552
 
575
- ## Example 2: A General Application Form
576
-
577
- ### Excel data
578
-
579
- <img width="1040" height="1615" alt="demo_form ja" src="https://github.com/user-attachments/assets/1997c5d7-eb93-4370-b2ff-6e8da34e79a0" />
553
+ ## Example 2: A General Application Form
554
+
555
+ ### Excel data
556
+
557
+ ![General application form Excel](docs/assets/demo_form.ja.png)
580
558
 
581
559
  ### ExStruct JSON
582
560
 
@@ -611,11 +589,11 @@ flowchart TD
611
589
  }
612
590
  ```
613
591
 
614
- ### ExStruct JSON -> Markdown via LLM reasoning
615
-
616
- ```md
617
- # Long-Term Care Insurance Burden Limit Certification Application
618
-
592
+ ### ExStruct JSON -> Markdown via LLM reasoning
593
+
594
+ ```md
595
+ # Long-Term Care Insurance Burden Limit Certification Application
596
+
619
597
  (Submitted to) Year Month Day
620
598
  Mayor of City X
621
599
 
@@ -649,21 +627,80 @@ If the applicant has not entered a care insurance facility, or uses short stay o
649
627
 
650
628
  ---
651
629
 
652
- ## Presence of a Spouse
653
-
654
- | Item | Value |
655
- | ---- | ----- |
656
- | Spouse | Yes / No |
657
-
658
- If "No", the following spouse section is not required.
659
-
660
- ---
661
-
662
- ## Notes
663
-
664
- 1. In this application, "spouse" includes a spouse living separately and a common-law partner.
665
- 2. If you own multiple assets of the same kind, list all of them and attach copies of bankbooks or equivalent documents.
666
- 3. If there is not enough space, write on the margin or on a separate sheet and attach it.
630
+ ## Presence of a Spouse
631
+
632
+ | Item | Value |
633
+ | ---- | ----- |
634
+ | Spouse | Yes / No |
635
+
636
+ If "No", the following spouse section is not required.
637
+
638
+ ---
639
+
640
+ ## Spouse Information
641
+
642
+ | Item | Value |
643
+ | ---- | ----- |
644
+ | Furigana | |
645
+ | Name | |
646
+ | Date of Birth | Meiji / Taisho / Showa Year Month Day |
647
+ | Personal Number | |
648
+ | Address | Postal code |
649
+ | Contact | |
650
+ | Address as of January 1 of this year (if different) | Postal code |
651
+ | Tax status | Municipal resident tax: taxable / non-taxable |
652
+
653
+ ---
654
+
655
+ ## Declaration of Income and Other Status
656
+
657
+ Check the applicable item below.
658
+
659
+ - □ 1. Livelihood protection recipient
660
+ - □ 2. Old-age welfare pension recipient in a household exempt from municipal resident tax
661
+ - □ 3. Person exempt from municipal resident tax whose taxable pension income + survivor/disability pension + other income totals **800,000 JPY or less per year**
662
+ - □ 4. Same as above, but **over 800,000 JPY up to 1,200,000 JPY**
663
+ - □ 5. Same as above, but **over 1,200,000 JPY**
664
+
665
+ Survivor pension includes widow's pension, widower's pension, mother's pension, quasi-mother's pension, and orphan's pension.
666
+
667
+ ---
668
+
669
+ ## Declaration of Deposits and Other Assets
670
+
671
+ - □ The total amount of deposits, securities, and other assets is below the following threshold:
672
+ - Category 2: 10 million JPY (20 million JPY for couples)
673
+ - Category 3: 6.5 million JPY (16.5 million JPY for couples)
674
+ - Category 4: 5.5 million JPY (15.5 million JPY for couples)
675
+ - Category 5: 5 million JPY (15 million JPY for couples)
676
+ - Second insured persons (ages 40-64): Categories 3-5 must be 10 million JPY or less (20 million JPY for couples)
677
+
678
+ ### Asset breakdown
679
+
680
+ | Item | Amount |
681
+ | ---- | ------ |
682
+ | Deposits | JPY |
683
+ | Securities (estimated value) | JPY |
684
+ | Other (including cash / debt) | JPY (describe) |
685
+
686
+ ---
687
+
688
+ ## Applicant Information (not required when the applicant is the insured person)
689
+
690
+ | Item | Value |
691
+ | ---- | ----- |
692
+ | Applicant name | |
693
+ | Contact (home / office) | |
694
+ | Applicant address | |
695
+ | Relationship to insured person | |
696
+
697
+ ---
698
+
699
+ ## Notes
700
+
701
+ 1. In this application, "spouse" includes a spouse living separately and a common-law partner.
702
+ 2. If you own multiple assets of the same kind, list all of them and attach copies of bankbooks or equivalent documents.
703
+ 3. If there is not enough space, write on the margin or on a separate sheet and attach it.
667
704
  4. If benefits are obtained through a false declaration, the paid amount and up to twice that amount as an additional charge may need to be repaid under Article 22, Paragraph 1 of the Long-Term Care Insurance Act.
668
705
  ```
669
706
 
@@ -690,9 +727,9 @@ This benchmark demonstrates that the library can:
690
727
 
691
728
  In short, **exstruct = "an engine that converts Excel into a format AI can understand."**
692
729
 
693
- ## Benchmark
694
-
695
- <img width="1440" height="720" alt="markdown_quality" src="https://github.com/user-attachments/assets/537bbc8c-8e09-433d-a910-6521274d2df5" />
730
+ ## Benchmark
731
+
732
+ ![Benchmark Chart](benchmark/public/plots/markdown_quality.png)
696
733
 
697
734
  This repository includes benchmark reports focused on RAG/LLM preprocessing of Excel documents.
698
735
  We track two perspectives: (1) core extraction accuracy and (2) reconstruction utility for downstream structure queries (RUB).