Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
3703 commits
Select commit Hold shift + click to select a range
859b1c9
fix(chart/html): #-prefix chart title and axis colors
goworm Jun 11, 2026
f7eb308
fix(pptx/html): render zero-thickness line shapes (divider rules)
goworm Jun 11, 2026
14d8757
fix(xlsx): stop producing files real Excel rejects (0x800A03EC)
goworm Jun 11, 2026
72c8938
fix(xlsx/html): sparkline honors its series color
goworm Jun 11, 2026
da8f09c
fix(word/html): paragraph spaceBefore no longer understated
goworm Jun 11, 2026
1b74fb4
fix(chart/html): chart fills default to full opacity, not 0.85
goworm Jun 11, 2026
4e8bc76
fix(word/html): well-formed markup around mid-paragraph page break
goworm Jun 11, 2026
aee3b8f
fix(xlsx/html): cellIs CF string equality now evaluated
goworm Jun 11, 2026
85a99cd
fix(chart): line/scatter series color written to a:ln (stroke), honor…
goworm Jun 11, 2026
aa4442b
fix(xlsx/html): General-format numbers round to 15 sig figs like Excel
goworm Jun 11, 2026
2b73322
fix(chart/html): filled radar areas use ~0.7 opacity (was 0.2)
goworm Jun 11, 2026
3d1b3ab
fix(word/html): monospace/serif fonts get correct generic fallback
goworm Jun 11, 2026
de518ba
fix(chart/html): area chart series paint in index order (z-order)
goworm Jun 12, 2026
2b48700
fix(xlsx/chart): series1=<range> populates numCache/strCache
goworm Jun 12, 2026
4fd1444
fix(pptx/add): table cell keys self-report unsupported + suggest 1-based
goworm Jun 12, 2026
f035f42
feat(xlsx): filter empty-cell worksheet bloat on open (#149)
goworm Jun 12, 2026
87381fb
refactor(chart/html): unify scatter rendering on RenderScatterChartSv…
goworm Jun 12, 2026
fe51d46
fix(xlsx): formula chains deeper than 256 references evaluate correctly
goworm Jun 12, 2026
469a4dc
fix(xlsx): blank cells inside conditional-formatting ranges render in…
goworm Jun 12, 2026
55bfb29
fix(docx): LaTeX aligned environments convert to OMML equation arrays
goworm Jun 12, 2026
69ce0c6
fix(chart): line-width values parse their unit instead of an uncondit…
goworm Jun 12, 2026
aaeba6b
fix(pptx): underline and strikethrough on a textless shape survive re…
goworm Jun 12, 2026
4c16fc1
feat(pptx): highlight property works across add, set, get and HTML pr…
goworm Jun 12, 2026
33e6de2
fix(docx): a pure theme run color reads back as the scheme name
goworm Jun 12, 2026
aa94d5b
fix(docx): table band sizes and tracked cell-merge tcPr rebuild as sc…
goworm Jun 12, 2026
6fd446b
fix(docx): field-result paragraph no longer hoists run formatting ont…
goworm Jun 12, 2026
e4e6144
fix(docx): customXml wrapper flattening warns deterministically, incl…
goworm Jun 12, 2026
ac7d3c8
fix(core): raw-set preserves whitespace-only text nodes in leaf elements
goworm Jun 12, 2026
3c0b425
fix(docx): dump synthesizes a schema-complete theme for an empty them…
goworm Jun 12, 2026
9912902
chore(release): bump version to 1.0.111
goworm Jun 12, 2026
db0cae5
chore: resolve the two remaining nullable-reference build warnings
goworm Jun 12, 2026
1e8a877
fix(docx): fractional percentage table and cell widths round-trip exa…
goworm Jun 12, 2026
3673a74
fix(docx): ActiveX form controls round-trip instead of being dropped
goworm Jun 12, 2026
75ec4c6
fix(docx): page-number and locale numbering formats round-trip
goworm Jun 12, 2026
5855a4c
fix(docx): a paragraph or character style's rPr language round-trips
goworm Jun 12, 2026
9dcc17b
fix(docx): SmartArt diagrams round-trip instead of being dropped
goworm Jun 12, 2026
458b849
fix(docx): cells wrapped by a cell-level content control stay first-c…
goworm Jun 12, 2026
fb323b5
fix(docx): VML shapes with relationship references round-trip
goworm Jun 12, 2026
75e9e63
fix(docx): customXml stores, webSettings, and latentStyles round-trip
goworm Jun 12, 2026
dbb50c9
fix(docx): footnote and endnote reference runs keep their direct form…
goworm Jun 12, 2026
2e1c557
fix(docx): auto line-spacing multipliers round-trip without twip loss
goworm Jun 12, 2026
60ed011
fix(docx): a paragraph mark's rtl flag round-trips
goworm Jun 12, 2026
1e47d99
fix(docx): a replayed table keeps its source column direction
goworm Jun 12, 2026
532b7ee
fix(docx): a picture's shape properties round-trip verbatim
goworm Jun 12, 2026
b94066d
fix(docx): footnote and endnote bodies keep their paragraph formatting
goworm Jun 12, 2026
0667c86
fix(docx): a floating picture keeps its text-wrap distances
goworm Jun 12, 2026
d1d32da
fix(docx): a package with a dangling part relationship opens
goworm Jun 12, 2026
9af67d0
fix(docx): a hyperlink that leads with a tab keeps its leader and pla…
goworm Jun 12, 2026
6b6a12f
fix(docx): anchored-picture raw-EMU posOffset capture accepts negativ…
goworm Jun 12, 2026
477181f
fix(docx): hyperlink run keeps explicit single underline, underline c…
goworm Jun 12, 2026
e3d5ff0
fix(docx): hyperlink run round-trips theme font slots, shading and ch…
goworm Jun 12, 2026
9908b99
fix(docx): underline.color no longer fabricates a single underline wh…
goworm Jun 12, 2026
c45b4d9
fix(docx): style toggle readback honors explicit-off values
goworm Jun 12, 2026
83b7399
fix(docx): anchored-picture relative positions accept the margin-edge…
goworm Jun 12, 2026
5275d31
fix(docx): rich block content controls with part references round-tri…
goworm Jun 12, 2026
09f3448
fix(docx): section-break paragraph keeps its anchored drawings; image…
goworm Jun 12, 2026
8fe34a6
fix(docx): cross-paragraph field chains inside a table cell round-tri…
goworm Jun 12, 2026
c016af7
fix(docx): mark-only paragraph rStyle no longer restyles the text run…
goworm Jun 12, 2026
5b37525
fix(docx): footnote/endnote/comment bodies keep tab-only runs
goworm Jun 12, 2026
9afe16b
fix(docx): add-style writes explicit-off bold/italic overrides
goworm Jun 12, 2026
ef10758
fix(docx): paragraph-mark theme font bindings round-trip under markRP…
goworm Jun 13, 2026
81bdafe
fix(docx): field runs keep per-slot and theme-bound fonts on replay
goworm Jun 13, 2026
debf3b6
fix(docx): legacy form-field bookmark ends in later paragraphs no lon…
goworm Jun 13, 2026
6df1d6e
fix(docx): legacy form fields keep auto checkbox size, empty results …
goworm Jun 13, 2026
b117e5c
fix(docx): set-paragraph text does not clone mark rPr when the call c…
goworm Jun 13, 2026
96d7326
fix(docx): footnote first-paragraph indent overrides round-trip
goworm Jun 13, 2026
447f39c
fix(docx): paragraph following a nested table reuses the auto-seeded …
goworm Jun 13, 2026
6df33f3
fix(docx): set-paragraph routes font.hint (and charspacing/charscale)…
goworm Jun 13, 2026
d8620ba
fix(docx): section-paragraph bookmarks emit; dangling bookmark closes…
goworm Jun 13, 2026
fcf8564
fix(docx): text-wrapping break round-trips its clear attribute
goworm Jun 13, 2026
469919b
fix(docx): zero line spacing (w:line=0 atLeast) round-trips
goworm Jun 13, 2026
244e222
fix(docx): picture crop accepts negative srcRect percentages
goworm Jun 13, 2026
5c9c8bc
fix(docx): chart and unsupported-content-type runs never take the dra…
goworm Jun 13, 2026
ba828eb
fix(docx): rich-block SDT with unshippable refs unwraps to its inner …
goworm Jun 13, 2026
a381005
docs: add official website officecli.ai to README headers
goworm Jun 13, 2026
bcd7e31
fix(docx): multi-section header/footer references attribute by replay…
goworm Jun 13, 2026
bd5ab15
fix(docx): floating (anchored) charts round-trip instead of being dro…
goworm Jun 13, 2026
1819daa
fix(docx): chart userShapes overlays round-trip instead of being dropped
goworm Jun 13, 2026
9e86bbd
fix(docx): chart title size/bold round-trips from the source defRPr
goworm Jun 13, 2026
0693183
fix(docx): chart axis-title weight and gridline/frame tints round-trip
goworm Jun 13, 2026
da432ba
fix(docx): footnote/endnote with no pStyle round-trips unstyled inste…
goworm Jun 13, 2026
eb543ef
fix(docx): docProps round-trip so data-bound content controls keep th…
goworm Jun 13, 2026
b97ed1e
fix(docx): table direction reads bidiVisual toggle value, not just pr…
goworm Jun 13, 2026
055d343
fix(docx): paragraph indent coalesces firstLine/hanging across split …
goworm Jun 13, 2026
d572f78
fix(docx): header/footer referenced by multiple types round-trips eve…
goworm Jun 13, 2026
6e6c699
fix(mcp): register Claude Code MCP in ~/.claude.json, not ~/.claude/s…
goworm Jun 13, 2026
2b9f6f2
fix(docx): bookmark name with /[] is kept on add, not rejected
goworm Jun 13, 2026
f931a60
fix(mcp): register Claude Code via official `claude mcp add`, fall ba…
goworm Jun 13, 2026
3292adb
fix(mcp): record a stable, upgrade-proof officecli path as the MCP co…
goworm Jun 13, 2026
e0bec72
fix(docx): run underline.color emits <w:u> in CT_RPr schema order
goworm Jun 13, 2026
9b236fa
fix(docx): header/footer/cell hyphen run keeps its text on round-trip
goworm Jun 13, 2026
f670206
chore(release): bump version to 1.0.112
goworm Jun 13, 2026
0fee6a7
fix(docx): legacy VML image (w:pict/v:imagedata) round-trips via inli…
goworm Jun 13, 2026
cd31aff
fix(docx): dedupe bookmark w:id document-wide so raw-set + structured…
goworm Jun 13, 2026
6f8ca8b
docs(skill): v1.0.112 — surface docx textbox rotation/gradient/shadow…
goworm Jun 13, 2026
f0eb089
fix(docx): single-run paragraph collapse preserves run color theme tail
goworm Jun 13, 2026
21b54e0
fix(docx): span bookmark start reuses source id so a raw-set-preserve…
goworm Jun 13, 2026
8a16731
docs(readme): surface dump pptx coverage + Word revisions/textbox + P…
goworm Jun 13, 2026
f35e61f
fix(docx): nested field in header/footer/cell round-trips verbatim (f…
goworm Jun 13, 2026
2978b72
fix(docx): bookmark end=true op tolerates id collisions (fixes TOC PA…
goworm Jun 13, 2026
f0dd113
fix(docx): block SDT as a table cell's sole content drops the auto-se…
goworm Jun 13, 2026
3aaf962
fix(docx): empty paragraph's mark rStyle round-trips so spacer line h…
goworm Jun 13, 2026
14212bf
fix(docx): section-carrier paragraph round-trips its inline control, …
goworm Jun 13, 2026
d0f3932
fix(xlsx): bulk get listing omits value-less empty cells so styled-em…
goworm Jun 13, 2026
a3a3884
fix(docx): picture with an SVG companion blip round-trips instead of …
goworm Jun 13, 2026
ef5faf4
fix(pptx): batch round of bug fixes across charts/clone/units/effects
goworm Jun 13, 2026
b7fd025
fix(docx): nested block SDT inside an unwrapped content control round…
goworm Jun 13, 2026
d30a78d
Merge branch 'main' of github.com:iOfficeAI/OfficeCLI
goworm Jun 13, 2026
24784c1
fix(docx): duplicate styleId round-trips its last definition (the one…
goworm Jun 13, 2026
bdf574f
fix(pptx): color transforms lumMod/satMod/hueMod accept percentages a…
goworm Jun 13, 2026
3d6dd3e
fix(pptx): accept OOXML system-color names (window/windowText) in col…
goworm Jun 13, 2026
a12278e
fix(pptx): textOutline color preserves transform chain and alpha on r…
goworm Jun 13, 2026
b923076
fix(pptx): table-cell border.compound accepts compound-line names
goworm Jun 13, 2026
aec864b
fix(pptx): shape fill inserts after custom geometry, not before it
goworm Jun 13, 2026
56e2e96
fix(pptx): resolve preset shape geometry by OOXML token, not just C# …
goworm Jun 13, 2026
715d264
fix(pptx): paragraph align accepts and round-trips dist/thDist/justLow
goworm Jun 13, 2026
0cb6202
fix(pptx): pictures and connectors can be added inside a group
goworm Jun 13, 2026
8cb40c6
fix(pptx): paragraphs add to, and set on, shapes inside nested groups
goworm Jun 13, 2026
37c052e
fix(pptx): set connector properties on a connector nested in a group
goworm Jun 13, 2026
deeb0fb
fix(docx): anchored picture preserves its custom wrap polygon instead…
goworm Jun 13, 2026
37ffed1
fix(docx): table round-trips its tblLook bitmask without re-enabling …
goworm Jun 13, 2026
2ddb692
fix(pptx): charts can be added inside a group
goworm Jun 13, 2026
6aeb4d6
fix(pptx): round-trip paragraph line-break attributes (eaLnBrk, latin…
goworm Jun 13, 2026
dc7490f
fix(pptx): declare extension namespaces on append-action slide raw-se…
goworm Jun 14, 2026
f9fed40
fix(pptx): register notesMasterIdLst in presentation.xml when a notes…
goworm Jun 14, 2026
691611e
fix(pptx): carry slideLayout external hyperlink relationships through…
goworm Jun 14, 2026
0650a5d
fix(docx): mid-document section carrier round-trips its page border
goworm Jun 14, 2026
e27218d
fix(pptx): emit each slide master's own theme part
goworm Jun 14, 2026
e2b4c62
fix(pptx): notes master retains its theme relationship
goworm Jun 14, 2026
2346c38
fix(docx): run-level w14 ligatures/numForm/numSpacing round-trip
goworm Jun 14, 2026
a654ded
fix(docx): dump clamps negative table-cell margin so rebuild stays clean
goworm Jun 14, 2026
a50e984
fix(pptx): preserve a group's cNvPr id so slide animations resolve th…
goworm Jun 14, 2026
1453bdb
fix(docx): table-cell textDirection accepts rotated vertical variants
goworm Jun 14, 2026
de4dc6b
fix(docx): styled-paragraph content control round-trips its paragraph…
goworm Jun 14, 2026
8735b01
fix(docx): no-result field round-trips its run font (theme face)
goworm Jun 14, 2026
667f7db
fix(pptx): round-trip the full paragraph bullet group, not just the b…
goworm Jun 14, 2026
21fc8d1
fix(docx): unwrapped content control preserves its cross-paragraph TO…
goworm Jun 14, 2026
042db8c
fix(pptx): shape txBody lstStyle content round-trips instead of empty…
goworm Jun 14, 2026
97ac30d
fix(pptx): table cell border lines round-trip verbatim instead of red…
goworm Jun 14, 2026
01df708
fix(pptx): table cell text body lstStyle and paragraph formatting rou…
goworm Jun 14, 2026
05252f7
fix(docx): batch round of HTML preview and Set/Add bug fixes
goworm Jun 14, 2026
7d7b042
fix(docx): second batch of HTML preview and Add/Set bug fixes
goworm Jun 14, 2026
96f3519
fix(docx): field with a drawing cached result round-trips its picture
goworm Jun 14, 2026
39b333a
fix(pptx): group-nested connector arrowheads and labels round-trip vi…
goworm Jun 14, 2026
b81d35d
fix(docx): paragraph set seeds a run for rStyle so collapsed cell tex…
goworm Jun 14, 2026
7afbb42
fix(docx): picture round-trips its hidden flag so an overlapping prin…
goworm Jun 14, 2026
ae4fb6f
fix(pptx): whitespace-only run text survives verbatim table-cell body…
goworm Jun 14, 2026
86144e5
fix(pptx): accept legacyMatte (and legacy 3D materials)
goworm Jun 14, 2026
385f5ec
Merge branch 'main' of github.com:iOfficeAI/OfficeCLI
goworm Jun 14, 2026
747a539
fix(pptx): line breaks can be added inside a group
goworm Jun 14, 2026
5c0814c
fix(docx): malformed hyperlink target degrades to plain text instead …
goworm Jun 14, 2026
360a2ec
fix(pptx): accept legacy 3D lighting rigs (legacyFlat/legacyNormal/le…
goworm Jun 14, 2026
e13718a
fix(pptx): background image parts round-trip via inlined add-part
goworm Jun 14, 2026
60a8f7b
fix(pptx): master/layout bg image survives an rId collision with a sc…
goworm Jun 14, 2026
1e6452b
fix(docx): smartTag/customXml-wrapped run round-trips in document order
goworm Jun 14, 2026
84a3e17
fix(docx): section page size round-trips its exact twips instead of a…
goworm Jun 14, 2026
e4ad1b0
fix(docx): smartTag/customXml-wrapped run round-trips its run formatting
goworm Jun 14, 2026
adeb15f
fix(pptx): SmartArt diagrams round-trip with parts and cached drawing
goworm Jun 14, 2026
5a9146d
fix(pptx): slideMaster id reconciled against layout ids so multi-mast…
goworm Jun 14, 2026
6c6a5a3
fix(docx): style id matching an element-type alias resolves as a styl…
goworm Jun 14, 2026
9416763
fix(docx): non-integer table row height no longer aborts the dump
goworm Jun 14, 2026
20fbdd0
fix(docx): form field round-trips to a document Word will open (uniqu…
goworm Jun 14, 2026
c23dd16
fix(pptx): slide-level background capture ignores timing-tree p:bg ta…
goworm Jun 14, 2026
8cf0355
fix(pptx): blockArc preset geometry no longer collapses to noSmoking
goworm Jun 14, 2026
98b37b8
fix(docx): table indent round-trips its percent unit instead of colla…
goworm Jun 14, 2026
de453ea
fix(pptx): drop slide animation targets that reference dropped shapes
goworm Jun 14, 2026
3d89e78
fix(docx): rich inline SDT in a header/footer table cell round-trips …
goworm Jun 14, 2026
d9b9dd0
fix(pptx): sysClr and prstClr fills round-trip instead of vanishing
goworm Jun 14, 2026
fdf15b5
fix(pptx): nested group's child coordinate system round-trips
goworm Jun 14, 2026
5af86aa
fix(pptx): shape image-fill framing (fillRect/srcRect) round-trips
goworm Jun 14, 2026
d3fc32e
fix(pptx): slide re-binds to its exact source layout by ordinal
goworm Jun 14, 2026
f9334ac
fix(pptx): Set run-style props on a runless paragraph land on endParaRPr
goworm Jun 14, 2026
d64794f
fix(docx): row tblHeader/cantSplit/hidden honor w:val="0" instead of …
goworm Jun 14, 2026
e67bc55
fix(docx): all CT_OnOff toggle reads honor w:val="0" project-wide, no…
goworm Jun 14, 2026
58ba477
fix(docx): table cell whose sole content is a block SDT drops the spu…
goworm Jun 14, 2026
6bd3256
fix(pptx): theme fmtScheme texture image round-trips instead of dangling
goworm Jun 14, 2026
b2a4c8c
fix(pptx): placeholder idx preserved at full uint range (no int overf…
goworm Jun 14, 2026
28193e6
fix(pptx): paragraph-level defRPr round-trips so bare runs keep their…
goworm Jun 14, 2026
f48c37f
fix(docx): VML shape / OLE object embedding round-trips its embedded …
goworm Jun 14, 2026
7bc8887
fix(docx): cross-paragraph field member with an external-rel hyperlin…
goworm Jun 14, 2026
4af3e43
fix(docx): form-field begin run keeps its typography so a sizeAuto ch…
goworm Jun 14, 2026
1b1609e
fix(docx): set on a paragraph applies run on/off toggles (smallCaps/c…
goworm Jun 14, 2026
c52dd76
fix(docx): form-field run formatting stamps only the field's own runs…
goworm Jun 14, 2026
7c7b827
fix(docx): field cached result keeps italic/underline/strike instead …
goworm Jun 14, 2026
34be2ab
fix(docx): VML/AlternateContent drawing embedding a chart round-trips…
goworm Jun 15, 2026
8591fc1
fix(pptx): relative-target file hyperlinks round-trip instead of failing
goworm Jun 15, 2026
641d2f4
fix(docx): nested-field cached result with a wrapping bookmark round-…
goworm Jun 15, 2026
1035b0e
fix(pptx): autofit shrink scale (fontScale/lnSpcReduction) round-trips
goworm Jun 15, 2026
497735f
fix(pptx): slide-size type round-trips instead of degrading to custom
goworm Jun 15, 2026
3e48cd0
fix(docx): settings keeps footnote/endnote separator refs when body n…
goworm Jun 15, 2026
3943771
fix(docx): settings keeps only the -1/0 note separator refs, not othe…
goworm Jun 15, 2026
053364f
fix(docx): cross-paragraph field closing in a section-carrier paragra…
goworm Jun 15, 2026
1bf148e
fix(pptx): layout/master tag-part reference round-trips instead of co…
goworm Jun 15, 2026
b8e7cda
fix(pptx): external hyperlink in speaker notes round-trips instead of…
goworm Jun 15, 2026
4ab645c
fix(pptx): pictures embedded in a SmartArt diagram round-trip instead…
goworm Jun 15, 2026
f818b8a
fix(docx): harden validation across add/set — invalid enums, numeric …
goworm Jun 15, 2026
da1ceb4
fix(docx): row-level cellSpacing and empty-paragraph vanish mark roun…
goworm Jun 15, 2026
8e5b179
chore(release): bump version to 1.0.113
goworm Jun 15, 2026
58ecc91
fix(pptx): picture blip companion parts (HD Photo / SVG) round-trip i…
goworm Jun 15, 2026
613ac92
fix(pptx): master / notes-master theme texture image round-trips inst…
goworm Jun 15, 2026
8e5bd2f
fix(docx): cell-nested rich SDT round-trips when the rebuilt cell has…
goworm Jun 15, 2026
6af00bb
fix(pptx): negative text-body inset round-trips instead of aborting t…
goworm Jun 15, 2026
93ca61a
fix(pptx): picture-bullet (buBlip) image round-trips instead of dangling
goworm Jun 15, 2026
9ca1ab6
fix(pptx): HD Photo layer on a master/layout picture round-trips inst…
goworm Jun 15, 2026
9ca4952
fix(pptx): extpart carrier re-homes a colliding scaffold rel instead …
goworm Jun 15, 2026
68a10d5
fix(pptx): group-child shape ids no longer collide with a sibling's p…
goworm Jun 15, 2026
bd36502
fix(docx): tcW-less cell after a horizontal merge derives its width f…
goworm Jun 15, 2026
7858651
fix(pptx): set on a picture nested in a group resolves instead of "El…
goworm Jun 15, 2026
0b60700
fix(pptx): external hyperlink in a table cell round-trips instead of …
goworm Jun 15, 2026
b834c05
fix(pptx): slide with two title/ctrTitle placeholders round-trips ins…
goworm Jun 15, 2026
f33abfe
fix(pptx): all bent/curved connector variants (2-5) round-trip instea…
goworm Jun 15, 2026
91d4541
fix(pptx): dataless chart round-trips instead of aborting the add
goworm Jun 15, 2026
a7bbbd8
fix(pptx): image text-fill on a slide round-trips instead of dangling
goworm Jun 15, 2026
3581b17
fix(pptx): internal slide-jump link in a table cell round-trips inste…
goworm Jun 15, 2026
8275614
fix(docx): table cell keeps a paragraph that follows a block content …
goworm Jun 15, 2026
f2f7996
fix(pptx): set on a picture in a NESTED group resolves instead of "El…
goworm Jun 15, 2026
3206ac6
fix(pptx): chart title color accepts a theme color instead of abortin…
goworm Jun 15, 2026
f568e10
fix(pptx): master/layout tag part re-homes a colliding scaffold rel i…
goworm Jun 15, 2026
19d1575
fix(pptx): master programmability tags are dropped (not dangled) so t…
goworm Jun 15, 2026
60e39ee
fix(pptx): pattern-fill scheme colors emit the token, not "SchemeColo…
goworm Jun 15, 2026
83dbcfa
fix(pptx): external image link on a master/layout round-trips instead…
goworm Jun 15, 2026
7523efa
fix(pptx): self-closing <a:t/> in a cell's txBodyRaw no longer corrup…
goworm Jun 15, 2026
b42879b
fix(pptx): signed color-transform offsets (satOff/lumOff/hueOff) roun…
goworm Jun 15, 2026
926ffd9
fix(docx): column add/remove/move/copy no longer corrupt a table with…
goworm Jun 15, 2026
71cb9b8
fix(pptx): presentation-level custom binary part (Google ppt/metadata…
goworm Jun 15, 2026
3040064
fix(pptx): image/tif content type is accepted as a TIFF alias instead…
goworm Jun 15, 2026
5a1950e
fix(pptx): SmartArt diagram external hyperlinks round-trip instead of…
goworm Jun 15, 2026
d917e05
merge(pptx): bring pptx round-trip fidelity fixes into main
goworm Jun 15, 2026
634047c
fix(docx): equation directly after a nested table in a cell survives …
goworm Jun 15, 2026
98f6b30
fix(pptx): embedded OLE object on a master/layout round-trips instead…
goworm Jun 15, 2026
75af00d
fix(docx): a second content control in a table cell round-trips inste…
goworm Jun 15, 2026
cf16905
merge(pptx): embedded OLE object on master/layout round-trips
goworm Jun 15, 2026
547949a
fix(docx): table-cell content control with a hyperlink/image round-tr…
goworm Jun 15, 2026
657fe87
Merge remote-tracking branch 'origin/main'
goworm Jun 15, 2026
d62d328
fix(docx): SDT carrier shipping inner tables advances the table ordin…
goworm Jun 15, 2026
13eb9ee
fix(xlsx): data-bar min/max=auto emits type=min/max cfvo instead of m…
goworm Jun 15, 2026
8406a6c
docs(examples): add conditional-formatting showcase covering the full…
goworm Jun 15, 2026
7b44d50
fix(docx): row-level content control wrapping a table row round-trips…
goworm Jun 15, 2026
53751d0
fix(core): validate no longer zeroes styles.xml on a document with un…
goworm Jun 15, 2026
d62d9c3
docs(examples): add document-formatting showcase for the docx documen…
goworm Jun 15, 2026
022b1e1
fix(docx): content control at a header/footer root registers its hype…
goworm Jun 15, 2026
21ba9f0
fix(docx): page break carried on a section-break paragraph round-trip…
goworm Jun 15, 2026
f002200
fix(docx): run inside a hyperlink round-trips its full character form…
goworm Jun 15, 2026
1d3f635
fix(xlsx): blank workbook ships a theme part so workbook theme.* set/…
goworm Jun 15, 2026
0875a3b
refactor(core): single Core entry for CT_EffectList schema-order inse…
goworm Jun 15, 2026
4bfdca9
fix(docx): round-tripped FORMCHECKBOX with an empty cached result no …
goworm Jun 15, 2026
1e06d45
fix(pptx): consolidate table-cell span into one canonical `colspan` (…
goworm Jun 16, 2026
ff986c2
fix(excel-html): chart overlays fill their anchor box and match Excel…
dragonwhites Jun 11, 2026
6e7b934
fix(excel-html): default and empty rows collapse below Excel's 15pt h…
dragonwhites Jun 11, 2026
2bbf8cd
fix(excel-html): stale chart-container margin offsets the overlay a r…
dragonwhites Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Binary file removed .docx
Binary file not shown.
159 changes: 134 additions & 25 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,23 @@ jobs:
os: ubuntu-latest
- rid: win-x64
name: officecli-win-x64.exe
os: ubuntu-latest
os: windows-latest
- rid: win-arm64
name: officecli-win-arm64.exe
os: ubuntu-latest
os: windows-latest
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4
defaults:
run:
shell: bash

- name: Clone wiki for embedded help
run: git clone "https://x-access-token:${{ github.token }}@github.com/${{ github.repository }}.wiki.git" src/officecli/wiki || echo "Wiki clone failed, using fallback help"

- name: Verify wiki version matches csproj version
run: |
CSPROJ_VERSION=$(grep '<Version>' src/officecli/officecli.csproj | sed 's/.*<Version>\(.*\)<\/Version>.*/\1/')
WIKI_VERSION=$(python3 -c "import json; print(json.load(open('src/officecli/wiki/version.json'))['version'])" 2>/dev/null || echo "unknown")
echo "csproj: $CSPROJ_VERSION, wiki: $WIKI_VERSION"
if [ "$WIKI_VERSION" != "$CSPROJ_VERSION" ]; then
echo "::error::Wiki version ($WIKI_VERSION) does not match csproj version ($CSPROJ_VERSION). Update wiki before building."
exit 1
fi
steps:
- uses: actions/checkout@v5

- name: Setup .NET
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'
dotnet-quality: 'preview'

- name: Publish
run: dotnet publish src/officecli/officecli.csproj -c Release -r ${{ matrix.rid }} -o publish --nologo
Expand All @@ -73,24 +63,143 @@ jobs:
mv publish/officecli publish/${{ matrix.name }}
fi

- name: Ad-hoc codesign (macOS)
- name: Setup macOS code signing
if: startsWith(matrix.rid, 'osx-')
run: codesign -s - -f publish/${{ matrix.name }}
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
CERT_PATH="$RUNNER_TEMP/build_certificate.p12"
KEYCHAIN_PATH="$RUNNER_TEMP/build.keychain-db"

echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode > "$CERT_PATH"

security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security import "$CERT_PATH" -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
security set-key-partition-list -S apple-tool:,apple:,codesign: -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security list-keychain -d user -s "$KEYCHAIN_PATH" login.keychain-db
rm -f "$CERT_PATH"

- name: Codesign (macOS)
if: startsWith(matrix.rid, 'osx-')
run: |
IDENTITY=$(security find-identity -v -p codesigning | grep "Developer ID Application" | head -n 1 | sed -E 's/.*"(.+)"/\1/')
echo "Signing with: $IDENTITY"
# --options runtime (Hardened Runtime, required by notarization) denies the
# self-contained CoreCLR's MAP_JIT executable memory by default, so the runtime
# fails to start with "Failed to create CoreCLR, HRESULT: 0x80070008" on every
# command. build/officecli.entitlements re-permits exactly allow-jit (the plist
# holds no XML comments — codesign's AMFI parser rejects them).
codesign --force --options runtime --entitlements build/officecli.entitlements --timestamp --sign "$IDENTITY" publish/${{ matrix.name }}
codesign --verify --strict --verbose=2 publish/${{ matrix.name }}
# Fail the build if allow-jit did not actually embed (e.g. a malformed plist
# makes codesign silently drop entitlements) — otherwise the bug ships again.
codesign -d --entitlements - --xml publish/${{ matrix.name }} | grep -q allow-jit

- name: Notarize (macOS)
if: startsWith(matrix.rid, 'osx-')
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APP_SPECIFIC_PASSWORD: ${{ secrets.APP_SPECIFIC_PASSWORD }}
TEAM_ID: ${{ secrets.TEAM_ID }}
run: |
# A bare Mach-O binary cannot be stapled; notarytool requires a
# zip/pkg/dmg container. Submit a zip — the notarization ticket is
# recorded on Apple's servers and Gatekeeper validates online.
ditto -c -k --keepParent publish/${{ matrix.name }} "$RUNNER_TEMP/notarize.zip"
xcrun notarytool submit "$RUNNER_TEMP/notarize.zip" \
--apple-id "$APPLE_ID" \
--team-id "$TEAM_ID" \
--password "$APP_SPECIFIC_PASSWORD" \
--wait
rm -f "$RUNNER_TEMP/notarize.zip"

- name: Smoke test - create document
if: >-
(matrix.rid == 'osx-arm64' && runner.arch == 'ARM64') ||
(matrix.rid == 'osx-x64' && runner.arch == 'X64') ||
(matrix.rid == 'linux-x64' && runner.os == 'Linux')
(matrix.rid == 'linux-x64' && runner.os == 'Linux') ||
(matrix.rid == 'win-x64' && runner.os == 'Windows')
env:
# Disable Git Bash (MSYS) POSIX-to-Windows path conversion on
# windows-latest, which otherwise mangles `/body` into
# `C:/Program Files/Git/body` before it reaches the CLI.
MSYS_NO_PATHCONV: '1'
MSYS2_ARG_CONV_EXCL: '*'
run: |
chmod +x publish/${{ matrix.name }}
publish/${{ matrix.name }} create test_smoke.docx
publish/${{ matrix.name }} add test_smoke.docx /body --type paragraph --prop text="Hello from CI"
publish/${{ matrix.name }} get test_smoke.docx /body/p[1]
publish/${{ matrix.name }} get test_smoke.docx '/body/p[1]'
publish/${{ matrix.name }} close test_smoke.docx
rm -f test_smoke.docx

- name: Smoke test - .NET 8-only runtime (linux-x64)
if: matrix.rid == 'linux-x64' && runner.os == 'Linux'
run: |
chmod +x publish/${{ matrix.name }}
mkdir -p smoke_net8
docker run --rm \
-v "$PWD/publish:/app:ro" \
-v "$PWD/smoke_net8:/work" \
-w /work \
mcr.microsoft.com/dotnet/runtime:8.0 \
bash -c "set -e; \
/app/${{ matrix.name }} create issue115.docx; \
/app/${{ matrix.name }} add issue115.docx /body --type paragraph --prop text='net8 smoke'; \
/app/${{ matrix.name }} close issue115.docx; \
/app/${{ matrix.name }} view issue115.docx text --json"

- name: Smoke test - install
if: >-
(matrix.rid == 'osx-arm64' && runner.arch == 'ARM64') ||
(matrix.rid == 'osx-x64' && runner.arch == 'X64') ||
(matrix.rid == 'linux-x64' && runner.os == 'Linux') ||
(matrix.rid == 'win-x64' && runner.os == 'Windows')
env:
MSYS_NO_PATHCONV: '1'
MSYS2_ARG_CONV_EXCL: '*'
run: |
publish/${{ matrix.name }} install
if [ "$RUNNER_OS" == "Windows" ]; then
test -f "$LOCALAPPDATA/OfficeCLI/officecli.exe" || { echo "FAIL: officecli.exe not found in %LOCALAPPDATA%\\OfficeCLI"; exit 1; }
"$LOCALAPPDATA/OfficeCLI/officecli.exe" --version
else
test -f "$HOME/.local/bin/officecli" || { echo "FAIL: officecli not found in ~/.local/bin"; exit 1; }
"$HOME/.local/bin/officecli" --version
fi

- name: Smoke test - install.sh / install.ps1
# Exercises the shell installers themselves (separate from the CLI's
# own `install` subcommand tested above). Downloads from
# d.officecli.ai with github fallback — validates the production
# mirror is reachable AND the in-repo script is syntactically and
# logically correct on each platform.
if: >-
(matrix.rid == 'osx-arm64' && runner.arch == 'ARM64') ||
(matrix.rid == 'osx-x64' && runner.arch == 'X64') ||
(matrix.rid == 'linux-x64' && runner.os == 'Linux') ||
(matrix.rid == 'win-x64' && runner.os == 'Windows')
shell: bash
env:
MSYS_NO_PATHCONV: '1'
MSYS2_ARG_CONV_EXCL: '*'
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
pwsh -NoProfile -ExecutionPolicy Bypass -File ./install.ps1
test -f "$LOCALAPPDATA/OfficeCLI/officecli.exe" || { echo "FAIL: officecli.exe not installed"; exit 1; }
"$LOCALAPPDATA/OfficeCLI/officecli.exe" --version
else
bash install.sh
test -f "$HOME/.local/bin/officecli" || { echo "FAIL: officecli not installed at ~/.local/bin"; exit 1; }
"$HOME/.local/bin/officecli" --version
fi

- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: ${{ matrix.name }}
path: publish/${{ matrix.name }}
Expand All @@ -103,7 +212,7 @@ jobs:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
path: artifacts

Expand All @@ -119,7 +228,7 @@ jobs:
cat SHA256SUMS

- name: Create Draft Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
with:
files: artifacts/**/*
generate_release_notes: true
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/skill-parity.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Skill parity

# Root SKILL.md is the file the public URL serves
# (https://d.officecli.ai/SKILL.md, raw GitHub URL) and is what
# `curl ... | bash` consumers fetch. skills/officecli/SKILL.md is a
# symlink to it — the spec-conforming location that `gh skill install`
# and `npx skills add` discover, and what the binary embeds.
#
# On macOS / Linux the symlink resolves transparently and this diff
# always passes. The check exists for the Windows case: git on Windows
# without core.symlinks=true checks out symlinks as plain text files
# containing the link target path (e.g. literal "../../SKILL.md"), so
# diff catches that corruption before it ships in a release build.

on:
push:
branches: [main]
pull_request:
paths:
- 'SKILL.md'
- 'skills/officecli/SKILL.md'
- '.github/workflows/skill-parity.yml'

permissions:
contents: read

jobs:
diff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Diff root SKILL.md vs skills/officecli/SKILL.md
run: |
if ! diff -q SKILL.md skills/officecli/SKILL.md; then
echo "::error::SKILL.md and skills/officecli/SKILL.md are out of sync."
echo "The two files must be byte-identical. The binary embeds skills/officecli/SKILL.md;"
echo "the public URL (d.officecli.ai/SKILL.md, raw GitHub) serves the root copy."
echo "Fix: cp SKILL.md skills/officecli/SKILL.md (or the reverse) and commit."
exit 1
fi
echo "OK: SKILL.md == skills/officecli/SKILL.md"
126 changes: 126 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Contributing to OfficeCLI

> 中文版 / Chinese version: [CONTRIBUTING.zh.md](./CONTRIBUTING.zh.md)

> You must follow the two rules below. Code style, dependencies, tests, and
> docs are handled by the maintainer in post-merge cleanup — do not worry
> about them.

## Rule 1: One PR = one atomic change

A PR must contain exactly one feature or one bug fix that cannot be further
decomposed. If your change can be split into multiple pieces that each have
standalone value, submit each piece as a separate PR.

### Self-check

Before opening the PR, ask your AI tool:

> "Analyze this diff. Can it be decomposed into multiple PRs where each
> could be merged or reverted independently? If yes, list them."

If the answer is "yes, N PRs", split into N PRs before submitting.

### Examples

**✅ Single-PR bugs** — one root cause, one fix
- `Picture added with only 'width' specified gets wrong default height`
- `Body-level find: anchor throws ArgumentException`
- `AddParagraph --index N is off-by-one when the body contains a table`

**✅ Single-PR features** — one coherent capability
- `query ole: list embedded OLE objects with ProgID and dimensions`
- `set wrap/hposition/vposition on floating pictures`

**❌ Must split** — multiple independent changes bundled together
- `Fix picture index bug + add OLE detection + add HTML heading numbering`
→ 3 PRs, zero shared code
- `Add OLE object detection + add EMF→PNG conversion`
→ 2 PRs, two independent layers
- `Add auto aspect ratio + fix index off-by-one + fix line spacing clipping`
→ 3 PRs, three unrelated root causes

**🤔 Judgment calls** — default to splitting
- `Add helper function + its first consumer`
→ 1 or 2 PRs; split if the helper has standalone reuse potential
- `Add read support + add write support for the same property`
→ 1 or 2 PRs; split if you want read to land before write is vetted

## Rule 2: Every PR must include a verifiable validation method

State in the PR description (or a linked issue) how a reviewer can confirm
your change actually works.

### For bug-fix PRs — pick one (in order of preference)

1. **officecli command sequence** showing broken output before and fixed
output after
2. **Shell or Python script** that reproduces the bug and runs clean after
the fix
3. **Authoritative reference** showing what the correct behavior should be
(OOXML spec, Microsoft / ECMA docs, etc.)
4. **Screenshot** — only when the bug is purely visual

### For feature PRs — include at minimum

- **A screenshot** of the feature in action (Word / Excel / PowerPoint
window, HTML preview, or terminal output)
- Optionally a command sequence showing how to trigger it

### Examples

**Bug fix — command sequence (ideal):**

```bash
# Before my fix:
officecli blank test.docx
officecli add test.docx picture --prop "path=photo-2x1.png" --prop "width=10cm"
officecli query test.docx picture
# → height: "10.2cm" ❌ WRONG (hardcoded 4-inch default)

# After my fix:
officecli blank test.docx
officecli add test.docx picture --prop "path=photo-2x1.png" --prop "width=10cm"
officecli query test.docx picture
# → height: "5.0cm" ✓ CORRECT (auto-computed from 2:1 pixel ratio)
```

**Feature — screenshot (ideal):**

> **Heading auto-numbering from style chain**
>
> Before: ![heading-before.png] (plain "Chapter One" with no number)
> After: ![heading-after.png] ("1. Chapter One" with auto-numbering span)
>
> How to trigger:
> ```bash
> officecli blank demo.docx
> officecli add demo.docx paragraph --prop "style=Heading1" --prop "text=Chapter One"
> officecli watch demo.docx
> ```

## If you don't follow these rules

The maintainer reserves two options.

### Option A — Reject and ask for resubmission (preferred)

The maintainer closes the PR with a link to this guide and asks you to
resubmit as properly decomposed PRs with validation methods.

**Your credit:** the PR is entirely yours, including the **"Merged"** badge
after resubmission.

### Option B — Cherry-pick the valuable parts (last resort)

If part of your PR is clearly valuable and worth saving, the maintainer runs
`git cherry-pick` on those commits into `main` directly and closes the
original PR.

**Your credit:**
- `git cherry-pick` preserves the original author, so `git log` and
`git blame` still show you as author of those lines.
- The maintainer's reconcile commit message carries a
`Co-authored-by: <you> <your-email>` trailer, which counts toward your
GitHub contribution graph.
- **However, the original PR shows as "Closed" instead of "Merged"**.
Loading