feat(cli): Batch completeness — 17 operations (GH-88)#219
Conversation
…ation (GH-88) Expand batch from 7 to 17 operations, making it the primary interface for atomic multi-step workbook modifications. This is especially impactful for LLM agents where each tool call is expensive. New operations: - comment/remove-comment: cell comment management - clear: clear contents/styles/comments with flags - col-hide/col-show/row-hide/row-show: visibility control - autofit: auto-fit column widths - add-sheet/rename-sheet: workbook-level sheet management Streaming mode supports col/row visibility ops; other new ops require full workbook mode with a clear error message. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
applyDomainRowProps used OR logic (props.hidden || row.hidden) which made it impossible to unhide a row once hidden — the original XML attribute always won. Domain properties should always override the preserved XML attributes, matching the documented behavior. Found during dogfooding of batch row-hide/row-show operations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Code Review: PR #219 - Batch Completeness (17 Operations)SummaryThis PR significantly expands the batch operations interface from 7 to 17 operations and includes an important OOXML bugfix for row/column visibility. Overall, this is high-quality, well-architected code that adheres to the project's strict functional programming principles. ✅ Strengths1. Architecture & Design
2. Functional Purity
3. OOXML Bugfix (Critical)The fix in // Before: hidden = props.hidden || row.hidden ❌ (OR logic made unhiding impossible)
// After: hidden = props.hidden ✅ (Domain always overrides XML)This correctly implements domain-over-XML semantics, enabling row/col hide→show round-trips. Well caught during dogfooding! 4. Documentation
5. Error Handling
🔍 Observations & Suggestions1. Test Coverage
|
…rvation 15 new in-memory batch operation tests covering comment, remove-comment, clear, col-hide/show, row-hide/show, autofit, add-sheet, rename-sheet including error cases (duplicate sheet, missing sheet, invalid column spec). Streaming improvements (agent contribution): - SAX-based readExistingWorksheetMetadata reads col/row properties from source worksheet before applying patches, preserving widths, outline levels, styles, and visibility state during streaming writes - StreamingTransform column writer now conditionally emits width/customWidth and properly handles styleId and collapsed attributes - Autofit column spec parsing extracted to pure Either-based helper with fail-fast error reporting 3 streaming-specific tests verify metadata preservation for col-hide and row-show round-trips. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Code Review - PR #219: Batch CompletenessSummaryThis PR successfully expands the batch API from 7 to 17 operations and fixes a critical OOXML bug preventing row/column unhiding. The implementation is solid, well-tested, and aligns with XL's architectural philosophy. ✅ Strengths1. Critical Bug FixThe OOXML fix in // Before: props.hidden || row.hidden (OR logic prevented unhiding)
// After: props.hidden (domain always wins)This fix properly allows unhiding rows/columns that were hidden in the original XML. The same pattern is correctly applied to 2. Comprehensive Test Coverage
3. Smart Streaming Mode HandlingThe implementation correctly identifies which operations work in streaming mode:
The explicit error message (lines 238-243 in 4. Metadata PreservationThe
5. AutoFit ImplementationThe
|
Summary
New batch operations (10)
comment{"op":"comment","ref":"A1","text":"Note","author":"User"}remove-comment{"op":"remove-comment","ref":"A1"}clear{"op":"clear","range":"A1:B10","all":true}col-hide{"op":"col-hide","col":"C"}col-show{"op":"col-show","col":"C"}row-hide{"op":"row-hide","row":5}row-show{"op":"row-show","row":5}autofit{"op":"autofit","columns":"A:F"}add-sheet{"op":"add-sheet","name":"Summary","after":"Sheet1"}rename-sheet{"op":"rename-sheet","from":"Old","to":"New"}OOXML bugfix
applyDomainRowPropsusedprops.hidden || row.hiddenwhich made unhiding impossible — the original XMLhidden="1"always won. Domain properties now always override preserved XML attributes.Test plan
./mill __.test)./mill __.checkFormat)🤖 Generated with Claude Code